使用createAsyncThunk时extraReducers无法更新状态问题求助
问题原因与修复方案
存在的核心问题
- 未触发
loadUser异步请求:你仅定义了异步Thunk,但没有调用dispatch触发请求,extraReducers不会自动执行,state自然不会更新 - 选择器返回值错误:
selectUserInfo当前返回整个Redux根状态,未正确取值你定义的getUser切片数据 api.js中user.json()缺少await关键字,存在异步逻辑隐患- 额外问题:App组件中
color是普通变量而非React状态,修改后不会触发视图重渲染,改色功能无法生效
分步修改代码
- 修复
getUserSlice.js中的选择器
// 替换原selectUserInfo代码 export const selectUserInfo = (state) => { return state.getUser; }; // 小优化:如果你的接口返回的是单个用户对象而非列表,可以把initialState的info初始值设为null,fulfilled回调中改为state.info = action.payload,不需要用push方法
- 修复
api.js的异步逻辑
export const fetchUserInfo = async () => { const user = await fetch('http://localhost:5000/api/user'); const json = await user.json(); // 补充await关键字 return json; }
- 修复
App.js的触发逻辑与渲染逻辑
import React, { useEffect, useState } from 'react'; import './App.css'; import {Container} from 'react-bootstrap'; import Achievement from './components/Achievement/Achievement'; import { useDispatch, useSelector } from 'react-redux'; import { selectUserInfo, loadUser } from './features/getUser/getUserSlice'; const colors = ['#010626','#4d6396', '#5d1a87', '#5d1a87', '#5d1a87']; function App() { // 将color改为React状态,保证修改后触发重渲染 const [color, setColor] = useState(colors[0]); const userState = useSelector(selectUserInfo) const dispatch = useDispatch(); // 组件挂载时触发用户信息请求 useEffect(() => { dispatch(loadUser()) }, [dispatch]) function changeColor() { const newColor = `rgb(${Math.round(Math.random() *256)}, ${Math.round(Math.random() *256)}, ${Math.round(Math.random() *256)})`; setColor(newColor); } return ( <div className="App" style={{ background: color }}> <Container> <h1 id="whoAmI"> Witaj na moim portfolio {/* 不要直接渲染整个对象,先判断状态再取对应字段渲染,字段名替换为你接口实际返回的字段 */} {userState.isLoading ? '加载中...' : userState.hasError ? '加载失败' : userState.info.map((user, idx) => <span key={idx}>{user?.name}</span>) } </h1> <button onClick={changeColor}> Zmień kolor tła </button> <div className="col-lg-4 col-md-6 col-sm-12"> <Achievement title="Ukończenie The Web Developer Bootcamp" picture="https://res.cloudinary.com/syberiancats/image/upload/v1630317595/k9g0nox2fyexxawg8whu.jpg" /> </div> </Container> </div> ); } export default App;
内容的提问来源于stack exchange,提问作者Maciej Kuta
相关产品推荐
相关产品推荐

