简体   繁体   中英

React.useState, will not update. How do I perform a instant update of React useState?

So I'm setting up a react useContext to share user's data such as the user's name and the login status etc... I make a request to the server every time a user refreshes the app to verify that if they have a valid token, the user can then be logged in. Great, but one problem I keep on running into with react is knowing how to get an instant update of useState, as this is needing to be updated as soon as the user is verified.

I've read that you have to create a new object so that React knows it's a new object and then it'll trigger a re-render... Just about every combination I can think of I've tried. Can someone please clarify for me how it's done?

Option 1:

   setUser(prev => {
    return { ...prev, ...newObj }
   })

Option 2:

   setUser({ ...newObj })

Can someone please give me the proper way to get a instant update to the React useState.

Thanks

import React, { useState } from "react";
import { useReadCookie } from "../hooks/cookies";
import UserContext from "./user-context";

const UserContextProvider = ({ children }) => {
  const readCookie = useReadCookie;

  const [user, setUser] = useState({
    name: null,
    userID: null,
    token: null,
    permissions: null,
    loginStatus: false,
    checkLoginStatusReady: false,
  });


  const loginStatus = async () => {
    return new Promise(async (resolve, rej) => {
      // So we'll reach out to the server and check to see if the
      // User is logged in

      const token = readCookie("token");

      if (token && token.length === 174) {
        // send a request to see if this is a valid user
        const req = await fetch("/api/checkLoginStatus.php");

        const res = await req.json();

        // console.log(res);
        handleLogUserIn(res);
      }

      console.log(user, "The state variable");
      resolve();
    });
  };

  const handleLogUserIn = (res) => {
    if (res.success === true) {
      const userObj = {
        name: res.name,
        userID: res.userID,
        token: res.token,
        permissions: res.permissions,
        loginStatus: true,
        checkLoginStatusReady: true,
      };

      console.log(userObj, "the user variable");

      setUser({ ...userObj });
    }
    else {
      console.log("Not going here");
      const userObj = {
        name: null,
        userID: null,
        token: null,
        permissions: null,
        loginStatus: false,
        checkLoginStatusReady: true,
      };
      setUser({ ...userObj });
    }
  };

  return (
    <UserContext.Provider
      value={{
        username: user.username,
        userID: user.userID,
        token: user.token,
        permissions: user.permissions,
        loginStatus: user.loginStatus,
        checkLoginStatusReady: loginStatus,
        setUser,
      }}
    >
      {children}
    </UserContext.Provider>
  );
};

export default UserContextProvider;

you can use useEffect for listening to the state update example if using

const [state, setState] = useState({
 username : "",
 status : "",
})

useEffect(() => {
   setState({
...state, 
username : state.username,
status : "active,
})
},[state])

or if using context: On parent provider.js:

import React, { useState } from 'react'

export const UserContext = React.createContext({
  username: "",
  status: "active",
  setUser: () => {}
})

export const UserContextProvider = (props) => {

  const setUser = (param) => {
    setState({...state, username: param.username, status: param.status})
  }

  const initState = {
   username: "",
   status: "active",
   setUser: () => {}
  } 

  const [state, setState] = useState(initState)

  return (
    <UserContext.Provider value={state}>
      {props.children}
    </UserContext.Provider>
  )
}

On Component:

import React, { useContext } from 'react'
import provider from './provider'

function Component() {

  const context = useContext(provider.UserContext)
  const onClick = () => {
    // do hit api
    if(token){
      state.setUser({username : "a", status:"inactive"})
    }
  }

  return (
    <provider.UserContextProvider>
      <buttin onClick={onClick}></button>
        <div>username : {state.username}</div>
        <div>status : {state.status}</div>
    </provider.UserContextProvider>
  )
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM