reactjs - useContext + useReducer 不会导致重新渲染(始终提供默认状态)
问题描述
在一个示例迷你应用程序中,我有 index.js 呈现<App />
(使用 ReactDOM.render 方法)。并且<App />
是:
import { useReducer } from 'react';
import AppContext, { defaultAppState } from './store/AppContext';
import AppReducer from './store/AppReducer';
import CitiesList from './components/CitiesList';
import AddCity from './components/AddCity';
export default function App() {
const [appState, dispatch] = useReducer(AppReducer, defaultAppState);
return (
<AppContext.Provider value={[ appState, dispatch ]}>
<CitiesList />
<AddCity />
</AppContext.Provider>
);
}
上下文在这样的文件(AppContext.js)中定义:
import React from 'react';
export const defaultAppState = {
cities: [
{name: 'CityA', temperature: 20},
{name: 'CityB', temperature: 12},
],
};
export default React.createContext(
defaultAppState
);
而reducer就是这个(AppReducer.js):
import { defaultAppState } from './AppContext';
import * as ACTIONS from './Actions';
const AppReducer = (state = defaultAppState, action) => {
switch(action.type) {
case ACTIONS.ADD_CITY:
const newCities = state.cities.concat([action.payload]);
return { ...state, cities: newCities };
default:
return state;
}
}
export default AppReducer;
在<AddCity />
组件中,我成功触发dispatch
并更新了减速器中的状态。(将 console.log 放在 之前return
并看到它应该是新状态。)但是,这不会触发重新渲染并且<CitiesList />
不会反映任何更改 - 它始终显示默认状态。
知道我做错了什么吗?
=====
编辑:添加代码<CitiesList />
:
import React, { useContext } from 'react';
import AppContext from '../store/AppContext';
export default function CitiesList() {
const [appState, dispatch] = useContext(AppContext);
const { cities } = appState;
return (
<>
<h1>Cities ({cities.length})</h1>
{cities.length > 0 &&
// Looping the cities array and showing the actual cities ..
}
</>
);
}
同时添加以下代码<AddCity />
:
import { useState, useReducer } from 'react';
import AppReducer from '../store/AppReducer';
import { ADD_CITY } from '../store/Actions';
export default function AddCity() {
const [appReducer, dispatch] = useReducer(AppReducer);
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>
</>
);
}
解决方案
推荐阅读
- html - 如何在行的中心显示所有值,并且行上方的 div 的宽度与其下方的行不同。如何做到这一点?
- javascript - webpackConfig 上的 ESM 导入
- javascript - 单击图标时从 localStorage 中删除项目及其数据
- python - 为什么我不能通过单击 .py 文件来运行 python 程序
- geometry - Revit API。如何获得多个元素的边界框?
- python - 带有附加点的最小/最大缩放
- python - 有点复杂的熊猫数据框,行到列
- java - EditText 条件循环 Android Studio
- c# - 如何跳过具有相同类名且具有“大于”条件的第一个元素
- r - 定位均匀间隔事件的日期