我有一个组件,它使用useContext
来检索全局状态,即电影/电视节目的列表。我正试图将此全局状态保存为本地状态,这样我就可以在单击按钮时按媒体类型(电影或电视节目(过滤列表,但过滤器应该只在本地反映,而不需要执行更改全局状态的操作(我不希望完整的列表丢失(。
但是,在将全局状态存储到本地状态之后,本地状态为空。这是组件的代码:
import React, { useContext, useState, useEffect } from "react";
import { WatchListContext } from "../../contexts/WatchListProvider";
import WatchItem from "../WatchItem";
const WatchList = () => {
const { state } = useContext(WatchListContext);
const [watchList, setWatchList] = useState(state);
const [filter, setFilter] = useState("");
useEffect(() => {
setWatchList((previousWatchlist) => {
const filteredWatchList = previousWatchlist.filter(
(watchItem) => watchItem.media_type === filter
);
return filteredWatchList;
});
}, [filter]);
return (
<div>
<div>
<button onClick={() => setFilter("tv")}>TV</button>
<button onClick={() => setFilter("movie")}>MOVIES</button>
</div>
{watchList
.filter((watchItem) => watchItem.media_type === filter)
.map(({ id, title, overview, poster_url, release_date, genres }) => (
<WatchItem
key={id}
title={title}
overview={overview}
poster_url={poster_url}
release_date={release_date}
genres={genres}
/>
))}
</div>
);
};
export default WatchList;
我不明白为什么这不起作用。任何帮助都将不胜感激!
您不能像(const [watchList, setWatchList] = useState(state);
(那样直接将global state
与local state
联系起来:-
-
这样做,它将自动与
context
中声明的state
的default
值绑定,该值始终为空array
或[]
。因此,为了绕过这一点,为什么不track
呢?state
的传入更改为useEffect
,如下所示:- -
WatchList.js
:-
import React, { useContext, useState, useEffect } from "react";
import { WatchListContext } from "../../contexts/WatchListProvider";
import WatchItem from "../WatchItem";
const WatchList = () => {
const { state } = useContext(WatchListContext);
const [watchList, setWatchList] = useState([]);
const [filter, setFilter] = useState("");
// handle fetching current changes of state received by Context
useEffect(() => {
(() => setWatchList(state))()
}, [state])
// handle filtering of data
useEffect(() => {
setWatchList((previousWatchlist) => {
const filteredWatchList = previousWatchlist.filter(
(watchItem) => watchItem.media_type === filter
);
return filteredWatchList;
});
}, [filter]);
return (
<div>
<div>
<button onClick={() => setFilter("tv")}>TV</button>
<button onClick={() => setFilter("movie")}>MOVIES</button>
</div>
{watchList
.filter((watchItem) => watchItem.media_type === filter)
.map(({ id, title, overview, poster_url, release_date, genres }) => (
<WatchItem
key={id}
title={title}
overview={overview}
poster_url={poster_url}
release_date={release_date}
genres={genres}
/>
))}
</div>
);
};
export default WatchList;