【问题标题】:Filter useContext state in a component without changing global state过滤组件中的 useContext 状态而不更改全局状态
【发布时间】:2021-03-17 15:43:40
【问题描述】:

我有一个使用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;

我不明白为什么这不起作用。任何帮助将不胜感激!

【问题讨论】:

    标签: reactjs use-state state-management react-state-management context-api


    【解决方案1】:

    您不能像以前那样 (const [watchList, setWatchList] = useState(state);) 那样直接将您的 global state 与您的 local state 联系起来:-

    • 通过这样做,它将自动与您在 context 中声明的 statedefault 值绑定,该值始终为 array[] 。所以要解决这个问题,你为什么不 track stateuseEffect 的传入更改,像这样:-

    • 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;
    

    【讨论】:

    • 谢谢,您的建议解决了特定问题,但也让我意识到逻辑还有其他问题,需要进一步重构。
    • 很高兴为您提供帮助
    猜你喜欢
    • 2022-12-12
    • 1970-01-01
    • 1970-01-01
    • 2021-07-14
    • 2021-06-16
    • 2016-01-02
    • 2018-09-26
    • 2018-07-30
    • 1970-01-01
    相关资源
    最近更新 更多