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

React Redux状态跨屏更新异常:首页获新状态,其他屏取旧值

React Redux状态更新后部分页面获取旧值的问题

问题场景

在Settings页面通过dispatch调用setUser方法更新user的name和profileId后,Home页面能通过useSelector获取并显示新的状态值,但切换到SecondScreen页面时,useSelector获取到的仍是旧的user状态值,且SecondScreen中依赖user.profileId的接口请求也使用了旧值。


相关代码

actions.js

export const SET_USER= "SET_USER";

export const setUser = user => ({
  type: SET_USER,
  payload: user
});

reducers.js

import { SET_USER } from "./actions";

const initialState = {
  user: {
    name: '',
    profileId: ''
  }
};

const userReducer = (state = initialState, action) => {
  switch (action.type) {
    case SET_USER: {
      return 
        ...state,
        user: action.payload
      };
    }

    default:
      return state;
  }
}

export default userReducer;

store.js

import AsyncStorage from '@react-native-async-storage/async-storage';
import { persistStore, persistReducer } from 'redux-persist'
import userReducer from './reducers';
import { createStore } from 'redux'

const persistConfig = {
  key: 'root',
  storage: AsyncStorage,
}

const persistedReducer = persistReducer(persistConfig, userReducer)

export const store = createStore(persistedReducer)
export const persistor = persistStore(store)

Home.js

const user = useSelector(state => state.user);

<Text>{user.profileId}<Text>

SecondScreen.js

const user = useSelector((state) => state.user);
const [profileData, setProfileData] =useState([]);


useEffect(() => {
  console.log("Here I wait updated profileId", user.profileId)
  apiGetProfile();
}, []);

const apiGetProfile = async () => {
  mainAxios
      .get('profiles/' + user.profileId, {})
      .then(function (response) {
        setLoading(false)
        if (response.status == 200) {

          setProfileData(response.data)
        } 
      })
      .catch(function (error) {
        console.log(error);
      });
  };

Settings.js

import { setUser} from './../../reduxStore/actions';
import { useDispatch } from 'react-redux';

const Settings = ({ navigation }) => {
  const changeProfile = id => {     
    dispatch(setUser({ name: "New name", profileId: "new id" }))
  };

}

问题原因及解决方案

1. Reducer语法错误导致状态未更新

你的userReducer中SET_USER分支存在**自动分号插入(ASI)**问题:return语句后直接换行,JavaScript会自动在return后添加分号,导致实际返回undefined,状态根本没有被更新。

修复代码:
将返回的对象用括号包裹,或者把{和return放在同一行:

case SET_USER: {
  return {
    ...state,
    user: action.payload
  };
}

2. SecondScreen的useEffect依赖项缺失

SecondScreen中的useEffect依赖数组为空,只会在组件首次挂载时执行一次。当user状态更新后,组件会重新渲染,但useEffect不会触发,导致接口请求依然使用旧的profileId。

修复代码:
将user.profileId加入依赖数组,确保状态变化时重新调用接口:

useEffect(() => {
  console.log("Here I wait updated profileId", user.profileId)
  apiGetProfile();
}, [user.profileId]); // 添加依赖项

3. 额外检查:Redux Store全局配置

确保你的根组件已通过Provider包裹store,且PersistGate配置正确,避免持久化逻辑导致的状态不同步:

import { Provider } from 'react-redux';
import { store, persistor } from './reduxStore/store';
import { PersistGate } from 'redux-persist/integration/react';

function App() {
  return (
    <Provider store={store}>
      <PersistGate loading={null} persistor={persistor}>
        {/* 你的导航/根组件 */}
      </PersistGate>
    </Provider>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 05:17:32