简体   繁体   English

React.useState,不会更新。 如何执行 React useState 的即时更新?

[英]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.因此,我正在设置一个 react useContext 来共享用户的数据,例如用户名和登录状态等...每次用户刷新应用程序时,我都会向服务器发出请求以验证他们是否具有有效的令牌,然后用户就可以登录了。很好,但是我在 react 中遇到的一个问题是知道如何获得 useState 的即时更新,因为一旦用户得到验证,就需要立即更新。

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.我读过你必须创建一个新的 object 以便 React 知道它是一个新的 object 然后它会触发重新渲染......几乎所有我能想到的组合我都试过了。 Can someone please clarify for me how it's done?有人可以为我澄清一下它是如何完成的吗?

Option 1:选项1:

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

Option 2:选项 2:

   setUser({ ...newObj })

Can someone please give me the proper way to get a instant update to the React useState.有人可以给我正确的方法来即时更新 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如果使用,您可以使用 useEffect 收听 state 更新示例

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

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

or if using context: On parent provider.js:或者如果使用上下文:在父 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>
  )
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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