useContext+useReducer状态更新成功但不触发重渲染 始终显示默认状态
问题原因
核心错误出在 <AddCity> 组件的实现上:
- 你在
<AddCity>组件内部重新调用了useReducer(AppReducer),创建了一套仅属于AddCity组件的局部状态和dispatch方法。你触发的是这个局部reducer的dispatch,仅更新了AddCity的内部状态,和App组件中存入Context的全局状态完全隔离,所以全局的appState根本没有发生变更,依赖全局状态的<CitiesList>自然不会触发重渲染。你之前在reducer函数中打印到的更新日志,对应的是这个局部reducer的执行,不是全局Context关联的reducer。 - 额外隐患:你创建AppContext时传入的默认值是
defaultAppState对象,但你给AppContext.Provider传递的value是[appState, dispatch]数组,二者结构不匹配。如果后续有组件在没有被AppContext.Provider包裹的场景下使用useContext(AppContext),解构数组会直接报错。
修复方案
- 优先修复
组件:删除局部的useReducer调用,改为从AppContext中获取全局的dispatch,代码修改后如下:
import { useState, useContext } from 'react'; import AppContext from '../store/AppContext'; import { ADD_CITY } from '../store/Actions'; export default function AddCity() { // 从Context取全局dispatch,删除原来的局部useReducer调用 const [appState, dispatch] = useContext(AppContext); const [name, setName] = useState(''); const onButtonClick = e => { const newCityData = { name: name, temperature: 18 }; dispatch({type: ADD_CITY, payload: newCityData}); setName(''); }; return ( <> <input value={name} onChange={e => setName(e.target.value)} /> <br/> <button onClick={onButtonClick}>Add city</button> </> ); }
- 可选优化Context默认值(解决结构不匹配隐患),修改AppContext.js的创建逻辑:
export default React.createContext( [defaultAppState, () => {}] );
内容的提问来源于stack exchange,提问作者pesho hristov
相关产品推荐
相关产品推荐

