【问题标题】:React - useState Hook with Context Api - can't copy a state array to another state arrayReact - useState Hook with Context Api - 无法将状态数组复制到另一个状态数组
【发布时间】:2021-01-14 19:34:01
【问题描述】:

我正在将一个数组导入“restMovies”,它工作正常 - 所有数据都在“restmovies”中,并通过上下文提供程序传递给应用程序的其余部分。

但是,我需要在数组中进行更改,因此我尝试将“restMovies”数组复制到“movies”数组,该数组将被传递到应用程序的其余部分。

但由于某种原因我不能“设置电影”,电影数组保持为空。

帮助?

export const MoviesContext = createContext();
export const MoviesContextProvider = (props) =>
{
        const [restMovies, setRestMovies] = useState([]);
        const [movies, setMovies] = useState([])

        useEffect(() =>
        {
            axios.get("https://api.tvmaze.com/shows").then(resp => setRestMovies(resp.data));
        }, [restMovies.values])


        useEffect(() =>
        {
            restMovies.map(item => 
            {
                setMovies([...movies, item])
            })

        }, [movies.values, restMovies.values])
     
        return (
          <MoviesContext.Provider value = {[movies]}>
             {props.children}
          </MoviesContext.Provider>)
}

【问题讨论】:

  • 我不明白,为什么你有 useEffect 听movies.values作为依赖?您是否尝试过在第一个 useEffect 挂钩中分配电影?

标签: arrays reactjs react-hooks context-api


【解决方案1】:

注意不要更新触发效果运行的相同值 因为这将在您的 setState 函数每次运行时重新触发。

export const MoviesContext = createContext();
export const MoviesContextProvider = (props) => {
  const [restMovies, setRestMovies] = useState([]);
  const [movies, setMovies] = useState([]);

  // This will execute once when the component mounts
  useEffect(() => {
    axios
      .get("https://api.tvmaze.com/shows")
      .then((resp) => setRestMovies(resp.data));
  }, []);

  // This will run when restMovies updates
  useEffect(() => {
    restMovies.map((item) => {
      setMovies([...movies, item]);
    });
  }, [restMovies]);

  return (
    <MoviesContext.Provider value={[movies]}>
      {props.children}
    </MoviesContext.Provider>
  );
};

【讨论】:

    【解决方案2】:

    问题

    movies.valuesrestMovies.values 始终未定义,因此依赖项值永远不会改变,并且效果回调永远不会重新触发(从安装时的初始触发)。映射数组也用于返回 new 数组,not 副作用如推入其他数组等...

    解决方案

    仅使用 restMovies 数组作为依赖项运行第二个效果(不要导致无限循环),并使用函数状态更新以正确地将当前moviesrestMovies 状态数组传播(复制)到新的数组引用中。我假设您可能还希望第一个效果在组件安装时运行一次以进行数据提取,因此请删除第一个效果的所有依赖项。

    useEffect(() => {
        axios.get("https://api.tvmaze.com/shows").then(resp => setRestMovies(resp.data));
    }, [])
    
    useEffect(() => {
      setMovies(movies => [...movies, ...restMovies])
    }, [restMovies])
    

    【讨论】:

    • 工作就像一个魅力,我现在更好地理解了依赖关系,谢谢:)
    【解决方案3】:

    您是否可能需要在 Movies setter 函数之外创建“restMovies”的副本,然后将其设置为新的电影状态?在你的第二次 useEffect - 钩子 像这样:

    const moviesCopy = [...movies,item];
    setMovies(moviesCopy);
    

    【讨论】:

      猜你喜欢
      • 2021-11-13
      • 2019-05-10
      • 1970-01-01
      • 1970-01-01
      • 2019-12-11
      • 1970-01-01
      • 2021-08-10
      • 2021-05-31
      • 2020-09-22
      相关资源
      最近更新 更多