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

使用Redux Toolkit的createAsyncThunk获取数据后state不更新

问题原因
  • Slice配置语法错误:你定义userSlice时,reducers: {}, 后面多写了一个多余的闭合大括号和逗号,导致extraReducers根本没有被传入createSlice的配置项中,请求成功后的更新逻辑完全不会执行。
  • 状态更新写法错误:就算修复了上述语法错误,你在extraReducers中直接对state参数赋值state = {...}的写法也是无效的。Redux Toolkit 内部集成了 Immer 库,支持两种更新状态的写法:要么直接修改state对象的属性,要么显式return新的状态对象。直接赋值给局部参数state,既没有修改Immer代理的状态,也没有返回新对象给Redux,状态不会更新。
  • 组件读取状态时机错误:useSelector获取的user属于当前渲染闭包中的值,哪怕你await等待异步请求执行完成,当前渲染周期的user仍然是初始值,只有组件触发重新渲染后,才能拿到更新后的状态,所以你在cacheResources函数内打印的永远是当前渲染的旧值。
  • 异步请求逻辑存在语法和异常隐患:你定义fetchUserById时,await API.getUser, { userID: userId }))存在语法错误,多了右括号且传参方式错误。如果请求触发catch分支,response会是undefined,后续执行return response.data.getUser会直接抛出异常。
解决方案

1. 修正userSlice.js代码

先删掉多余的闭合大括号,再修改状态更新逻辑,两种写法二选一即可:

写法1:直接修改state属性(推荐,Immer会自动处理 immutable 更新)

export const fetchUserById = createAsyncThunk(
  'user/fetchUserById',
  async (userId, thunkAPI) => {
    try {
      // 修正请求传参语法错误
      const response = await API.getUser({ userID: userId });
      return response.data.getUser
    } catch (e) {
      console.log(e)
      // 可选:抛出异常让thunk进入rejected状态,方便后续处理错误
      return thunkAPI.rejectWithValue(e)
    }
  }
);

export const userSlice = createSlice({
  name: 'user',
  initialState: {user: {}},
  reducers: {},
  // 删掉原来这里多余的闭合大括号
  extraReducers: (builder) => {
    builder.addCase(fetchUserById.fulfilled, (state, action) => {
      // 直接修改state的属性即可
      state.user = action.payload
    });
  }
});

export default userSlice.reducer

写法2:显式返回新状态对象

extraReducers: (builder) => {
  builder.addCase(fetchUserById.fulfilled, (state, action) => {
    return {
      ...state,
      user: action.payload
    }
  });
}

2. 修正组件中状态验证方式

如果要确认状态是否更新,不要在请求触发函数内打印,改为在组件顶层打印或者用useEffect监听user变化:

import AppLoading from 'expo-app-loading';
import React, { useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux'
import { fetchUserById } from '../../redux/slices/userSlice';

const AppLoadingScreen = (props) => {
  const user = useSelector(state => state.userReducer.user)
  const dispatch = useDispatch()
  
  // 组件重新渲染时会打印最新的user
  console.log("最新user状态:", user)

  // 监听user变化,更新时触发回调
  useEffect(() => {
    console.log("user已更新:", user)
  }, [user])
  
  const cacheResources = async () => {
    await dispatch(fetchUserById('00'));
  }

  return (
    <AppLoading
      startAsync={cacheResources}
      onFinish={() => {props.setIsReady(true)}}
      onError={console.warn}
    />
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 18:45:05