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
相关产品推荐
相关产品推荐

