在不更改全局状态的情况下筛选组件中的useContext状态



我有一个组件,它使用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 statelocal state联系起来:-

  • 这样做,它将自动与context中声明的statedefault值绑定,该值始终为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;

最新更新