Home > OS >  React Context State Update
React Context State Update

Time:06-28

I need help updating a user within various parts of my react app. I have successfully been able to create a context and access it globally, but anytime I try to update the state, it either breaks or uses default state I have issues updating the state, the code goes here

  1. Context File

     import { createContext } from "react"; 
     const user = {
       Fullname: "Ade Johnson",
       username: "Jonny",
       phone: " 234 0987655",
       email: "[email protected]",
       mode: "light",
       isLoggedIn: false,
     };
    
     export const UserContext = createContext(user);
    
  2. App.js

     import { UserContext } from "../User";
     const providerValue = useMemo(() => ({ user, setUser }), [user, setUser]);
     const { user, setUser } = useContext(UserContext);
     <UserContext.Provider value={providerValue}>
     {Children}
     </UserContext.Provider>
    

3.Login.js

function Login() {
  const [username, setUsername] = useState("");
  const [pass, setPass] = useState("");

  const { user, setUser } = useContext(UserContext);

  function proceed(url) {
let newArr = {...user};
newArr[0].isLoggedIn = true;
newArr[0].Fullname = "Toluwalope";
newArr[0].username = "Toolz";
newArr[0].email = "[email protected]";
setUser(newArr);
console.log(user);
window.location.replace(url);
 }
  1. Dashboard.js

     import React, { useContext, useEffect } from "react";
     import { UserContext } from "../User";
    
     function Dashboard() {
      const { user } = useContext(UserContext);
       return (
     <div className="container-fluid" id="main">
     <h5 className="mt-5 pt-5">Welcome {user[0].username},</h5>
     </div>
     );
     };
     export default Dashboard;
    

At this point, When the dashboard is loaded, it uses the default state.

CodePudding user response:

You're mixing up your data structures. You should destructure from useContext with an array (not an object), and your user object should be an object (not an array):

const [user, setUser] = useContext(UserContext);

And

const newUser = { ...user, isLoggedIn: true }; // etc

CodePudding user response:

Context.jsx

import React from 'react'

export const Store = React.createContext({})


export default function StoreProvider({children}){
   const [user, setUser] = React.useState({...you user properties})

   return(
     <Store.Provider value={{
       user, setUser
     }}
     >
       {children}
     </Store.Provider>
   )
}

App.jsx

import StoreProvider from 'path/to/store_provider.jsx'

export default function App(){

   return (
     <StoreProvider>
        //here you add your components that you want 
        // to have access to the store or your router    
     </StoreProvider>

   )
}

Login.jsx

import React from 'react'
import {Store} from 'path/to/store'

export default function Login(){
  //now you can update user successfully like this
  // setUser(prev => {...prev, newKey: newValue})
  const {setUser} = React.useContext(Store)
  

  return (
   //your jsx here
  )
}

Dashboard.jsx

import React from 'react'
import {Store} from 'path/to/store'

export default function Dashboard(){

   //now you can read user successfully like so
   // user.FirstName etc.
   //updating user from other components will update this view automatically
   const {user} = React.useContext(Store)

   return (
     //your jsx here
   )
}

Your code in general doesn't compile the way you are showing it to us. But even if you omitted some parts, there are two flaws.

  1. You are passing user directly to the StoreProvider value which means that you can destructure Fullname, username etc. from the store and not {user, setUser}
  2. You are not passing setUser to the StoreProvider value which means that you can't destructure it, and can't update your state. Later you do something with useMemo() but this is iffy. It may work, it may not, or it may cause bugs. Usually you want to pass a state or a reducer to the StoreProvider value.

Also useMemo() is not needed. Check docs for the most suitable usecases of useMemo().

  • Related