Search code examples
javascriptreactjsreact-redux

React redux state not updated in every screen, useSelector gets new state at Home Screen but gets previous state on another screen


I am working with React Redux, I can't understand why it brings the former state again.

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

I refresh user data from server with user.profileId here

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" }))
  };

}

I change user name and id in settings screen with dispatch, then on Home screen I observe new values but then I move to Second screen I get former old values there.


Solution

  • The problem appears to be with you useEffect hook.

    The second parameter of the hook is its dependency array - when this array is empty you are telling React to only run the hook on the first render cycle.

    Changing your hook to the following should help:

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

    That said - it isn't clear if there is anything missing from your code. You only havea console.log in useEffect which isn't necessary (you don't need useEffect for this), and useSelector will trigger a re-render, so if you use user.profileId in JSX code I would expect it to update.