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

useContext+useReducer状态更新成功但不触发重渲染 始终显示默认状态

问题原因

核心错误出在 <AddCity> 组件的实现上:

  1. 你在 <AddCity> 组件内部重新调用了 useReducer(AppReducer),创建了一套仅属于AddCity组件的局部状态和dispatch方法。你触发的是这个局部reducer的dispatch,仅更新了AddCity的内部状态,和App组件中存入Context的全局状态完全隔离,所以全局的appState根本没有发生变更,依赖全局状态的 <CitiesList> 自然不会触发重渲染。你之前在reducer函数中打印到的更新日志,对应的是这个局部reducer的执行,不是全局Context关联的reducer。
  2. 额外隐患:你创建AppContext时传入的默认值是 defaultAppState 对象,但你给AppContext.Provider传递的value是 [appState, dispatch] 数组,二者结构不匹配。如果后续有组件在没有被AppContext.Provider包裹的场景下使用useContext(AppContext),解构数组会直接报错。

修复方案

  1. 优先修复组件:删除局部的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>
    </> 
  );  
}
  1. 可选优化Context默认值(解决结构不匹配隐患),修改AppContext.js的创建逻辑:
export default React.createContext(
  [defaultAppState, () => {}]
);

内容的提问来源于stack exchange,提问作者pesho hristov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 23:06:07