React项目使用Context API报错useContext不可迭代
问题根因
你遇到的Uncaught TypeError: useContext(...) is not iterable属于运行时类型错误,语法层面无问题,因此webpack可以正常编译,只有浏览器执行代码时才会触发,核心问题出在Context传值和消费时的结构不匹配:
- 核心错误在
RoutesTree.js的useMemo写法:你写的() => ((state, setState))使用了圆括号包裹的逗号表达式,JS中逗号表达式会依次执行括号内的语句,最终只返回最后一个操作数,也就是这里实际传给Context的value只有setState这一个函数,根本不是你预期的[state, setState]二元数组。函数没有内置迭代器接口,无法用数组解构语法const [state, setState] = xxx读取,直接抛出不可迭代的错误。 - 次要问题是Context默认值和实际传值结构不一致:你初始化
DEFAULT_STATE时定义的是带state、setState属性的对象,和你想传递的数组结构完全不匹配,后续如果有组件脱离Provider包裹读取Context,同样会触发同类错误。
修复步骤
- 修改
RoutesTree.js,修正Context默认值结构、useMemo返回值和依赖项:
// 默认值和实际传值保持一致的数组结构 const DEFAULT_STATE = [ { users: [], teams: [] }, () => {} ]; export const AppContext = createContext(DEFAULT_STATE); const RoutesTree = () => { const [state, setState] = useState(DEFAULT_STATE[0]); // 把原来包裹返回值的圆括号改成方括号,返回真正的数组 const value = useMemo( () => [state, setState], // 补全setState依赖,useState返回的setState是稳定引用,不会触发多余重渲染 [state, setState] ); console.log('state', state); return ( <AppContext.Provider value={value}> <Routes> <Route path='/' element={<App />} /> <Route path='/teams/:id' element={<Team />} /> </Routes> </AppContext.Provider> ) } export default RoutesTree;
- 补全
Home.js缺失的组件返回逻辑,修正useEffect依赖项即可,你写的状态更新逻辑本身没有问题:
const Home = () => { const [state, setState] = useContext(AppContext); useEffect(() => { const getTeams = async () => { const response = await axios.get(teamsApiUrl); setState((prevState) => ({ teams: response.data, users: prevState.users })); } getTeams(); }, [setState]) // 补全组件需要渲染的JSX内容 return <div>Home Page</div> }
修改完成后刷新页面,报错就会消失,接口请求返回后可以正常读取到teams数据。
内容的提问来源于stack exchange,提问作者Alvaro Silva
相关产品推荐
相关产品推荐

