'I would like to update only one state and return the updated state in reactjs

I have a nodejs and reactjs web application. Though I am still learning reactjs. I have a system where users login, I captured the user's name, id and token coming from my nodejs: I am using react useContext() to mange the app's state.

Login:

dispatch({type: "LOGIN_START"})
        try{
        const response = await axios.post("/auth/login", {
            username: userRef.current.value,
            password: passwordRef.current.value
        });
        console.log(response.data.token)
        dispatch({type:"LOGIN_SUCCESS", payload: response.data.user, tokenData:  response.data.token});
       
    }catch(err){
        dispatch({type: "LOGIN_FAILURE"})
    };

I saved the response.data.user and response.data.token in my localstorage.

 const INITIAL_STATE = {
 user: JSON.parse(localStorage.getItem("user")) || null,
 token: JSON.parse(localStorage.getItem("token")) || null,

  export const Context = React.createContext();

  export const ContextProvider = ({children}) =>{
  const [state, dispatch] = useReducer(Reducer, INITIAL_STATE);

 //useEffect to enable the user details to be stored in their local storage
   useEffect(() => {
    localStorage.setItem("user", JSON.stringify(state.user, ));
     localStorage.setItem("token", JSON.stringify(state.token, ));
     
  }, [state.user], [state.token]);

  return(
    <Context.Provider value={{
        user:state.user,
        token: state.token,
        dispatch,
    }}>
        {children}
    </Context.Provider>
)
};

I created the login action like this which enabled me to capture the user's details and token:

export const LoginSucess = (user, token) => ({
type: "LOGIN_SUCCESS", 
payload: user,
tokenData: token

 });

And the useReducer was written like this:

 case "LOGIN_SUCCESS":
       return{
        user: action.payload,
         token: action.tokenData,

       };

If I want to update the token alone, it does't work as I wanted. Here is the code:

  case "UPDATE_TOKEN":
        return{
            ...state,
            token: action.tokenData,
            isFetching: false,
            error: true,
           
        };

It just does't update at all. If I remove ...state, it will update the token but the state.user will become undefined.

If I dont separate the token and user's details during sign-in action, it becomes a problem when the user wants to update their profile. Surely, the user wouldn't be updating their token when updating their profile and this will return user's details without a token. Token is updated via refresh token route or when user logs-in again. I want to separate the token state from the user's name and id state. The token changes every 15 minutes, needs to have it own state. How do I implement this?



Solution 1:[1]

I decided to create another usecontext and usereducer to handle the token state since it will always change every 15 minutes.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 kinhs