React - useState Hook with Context Api - 无法将状态数组复制到另一个状态数组

React - useState Hook with Context Api - can't copy a state array to another state array

我正在将一个数组导入“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>)
}

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

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

问题

movies.valuesrestMovies.values 始终未定义,因此依赖值永远不会改变并且效果回调永远不会 re-triggered ( 从挂载时的初始触发)。映射数组也是为了返回 new 数组,not side-effects 就像推入其他数组等...

解决方案

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

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

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

注意不要将触发效果的相同值更新为 运行 因为这将 re-trigger 每次你的 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>
  );
};