能否通过此方式向Redux State中添加数据?附代码示例
答案是不行。Redux的dispatch方法必须接收一个包含type字段的action对象,你代码里直接dispatchdata.totalResults这个数值的话,Redux会直接报错——因为reducer根本无法识别这种没有类型标识的“action”。
不过你可以用非常简单的方式实现类似的效果,不用复杂的异步逻辑(当然如果是把整个请求逻辑放到Redux里管理,那确实需要异步处理,但你这里的核心需求是把请求得到的数值存入Redux,下面是实现方法):
1. 基础Redux写法:定义action和reducer
首先得先给这个更新操作定义一个action类型,以及对应的reducer处理逻辑:
第一步:写一个action creator
这是一个返回action对象的简单函数:
// 可以单独放在actions.js文件里 export const setTotalResults = (total) => ({ type: 'SET_TOTAL_RESULTS', payload: total });
第二步:在reducer中处理这个action
在你的reducer里添加对应的case,接收这个action并更新状态:
// reducers/newsReducer.js const initialState = { totalResults: 0, // 其他你需要的状态字段... }; export const newsReducer = (state = initialState, action) => { switch (action.type) { case 'SET_TOTAL_RESULTS': return { ...state, totalResults: action.payload }; // 其他状态更新的case... default: return state; } };
第三步:在组件中正确dispatch
回到你的组件里,调用这个action creator并dispatch返回的对象就行:
const dispatch = useDispatch(); // 注意你代码里拼错了,是dispatch不是dispath useEffect(() => { fetch(`https://newsapi.org/v2/top-headlines?country=${location.state}&apiKey=${apiKey}`) .then(res => res.json()) .then(data => { setNewsAll(data) console.log(data) setLoadingNews(false) // 这里调用action creator,把数值传进去再dispatch dispatch(setTotalResults(data.totalResults)) }) }, [location, dispatch])
2. 更简洁的Redux Toolkit写法(推荐)
如果用Redux Toolkit(现在官方推荐的Redux写法),可以用createSlice直接生成action和reducer,省掉很多样板代码:
// slices/newsSlice.js import { createSlice } from '@reduxjs/toolkit'; const initialState = { totalResults: 0, // 其他状态字段... }; const newsSlice = createSlice({ name: 'news', initialState, reducers: { setTotalResults: (state, action) => { // Redux Toolkit内部用了Immer,允许直接修改state state.totalResults = action.payload; } } }); // 导出自动生成的action creator export const { setTotalResults } = newsSlice.actions; export default newsSlice.reducer;
组件里的用法和上面完全一样,直接dispatchsetTotalResults(data.totalResults)就可以了。
关于异步的补充
你提到知道应该用异步操作,其实如果只是在组件里发起请求,拿到数据后更新Redux状态,上面的写法完全没问题——异步请求已经在组件的useEffect里处理了,不需要额外的Redux异步中间件。但如果要把整个请求逻辑都放到Redux中管理(比如多个组件需要复用这个请求逻辑),那可以用Redux Toolkit的createAsyncThunk来封装异步逻辑。
内容的提问来源于stack exchange,提问作者Karol synter

