You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中使用useState与Context Api无法复制状态数组到另一状态数组

问题分析与解决方案

嘿,我瞅了下你的代码,问题主要出在这几个地方,咱们一步步来改:

1. 第一个useEffect的依赖错误

你写的依赖是[restMovies.values],但restMovies是个数组,根本没有values属性呀!而且这个请求只需要在组件挂载时执行一次,所以依赖应该是空数组[],不然要么不会触发请求,要么可能导致无限请求循环。

2. 第二个useEffect的双重问题

  • 依赖错误:同样用了movies.values和restMovies.values,这俩都是不存在的属性,正确的依赖应该是[restMovies]——只有当restMovies的数据更新时,我们才需要同步到movies里。
  • 循环更新movies的方式错误:你用map循环调用setMovies([...movies, item]),这里的movies是闭包捕获的初始空数组,所以每次循环都是把当前item放到空数组里,最后只会留下最后一个元素,而且多次调用setMovies还会导致不必要的重复渲染。

修正后的完整代码

import { createContext, useState, useEffect } from 'react';
import axios from 'axios';

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更新时,同步到movies数组
  useEffect(() => {
    // 确保restMovies有数据再更新
    if (restMovies.length) {
      // 用扩展运算符做浅拷贝,或者直接setMovies(restMovies)(如果不需要修改原数组的话)
      setMovies([...restMovies]);
    }
  }, [restMovies]); 

  // 如果后续需要修改movies,建议把setMovies也放进Context里,方便子组件调用
  return (
    <MoviesContext.Provider value={{ movies, setMovies }}>
      {props.children}
    </MoviesContext.Provider>
  )
}

额外小建议

你原来的Context value只传了[movies],如果后续需要在子组件里修改movies的话,最好把setMovies也传进去,像上面代码那样用对象传递,可读性更强。

内容的提问来源于stack exchange,提问作者Hadar Rosenman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 10:57:57