React-带有上下文Api的useState Hook-无法将状态数组复制到另一个状态数组

时间:2020-09-29 08:06:05

标签: arrays reactjs react-hooks context-api

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

但是,我需要在数组中进行更改,因此我试图将“ restMovies”数组复制到“ movies”数组,该数组将成为依赖于应用程序其余部分的数组。

但是由于某些原因我无法“ setMovies”,电影数组仍然为空。

帮助?

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>)
}

3 个答案:

答案 0 :(得分:1)

是否可能需要在“电影”设置器功能之外创建“ restMovies”的副本,然后将其设置为新电影状态?在第二次使用中-钩子 像这样:

focused

答案 1 :(得分:1)

问题

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

解决方案

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

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

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

答案 2 :(得分: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>
  );
};