簡體   English   中英

React useState 鈎子未在異步 useEffect 內更新

[英]React useState hook not updating within async useEffect

我想用我保存在 localStorage 中的對象覆蓋用戶,但它不起作用。

注意,組件被稱為Index因為我使用的是 next.js

import React, { useState, useEffect } from 'react';
import { loadUser } from '../utils/user';

const Index = () => {
  const [ user, setUser ] = useState({});

  async function restore(){
    const loadedUser = await loadUser();
    console.log(loadedUser);                    // correct - {userId: 4124783261364}
    setUser(loadedUser); 
    console.log(user);                          // was not updated - {}
  };

  useEffect(() => {
    restore();
  }, [0])

  return (<></>);
};

export default Index;

問題

  • 如果您只想運行效果並僅將其清理一次(在mountunmount 上),您可以傳遞一個空數組 ( [] )(不是[0] )作為第二個參數。 這告訴 React 你的 effect不依賴於來自 props 或 state 的任何值,所以它永遠不需要re-run
  • 繼承 React.Component 或 React.PureComponent 創建的Class 組件中的 setState 非常相似,使用useState hook提供的 updater 進行狀態更新也是異步的不會立即反映出來 這就是為什么console.log(user); setUser(loadedUser);旁邊不顯示更新的值setUser(loadedUser);

解決方案

  const restore = async () => {
    const loadedUser = await loadUser();
    console.log(loadedUser);                    // correct - {userId: 4124783261364}
    setUser(loadedUser); 
    console.log(user);                          // user is not updated here, but will be
  };

  useEffect(() => {
    restore();
  }, []);

類似情況

遠離您的問題,因為您只需要從本地存儲加載用戶一次。 但是當loadUser()按時間返回變化的結果因此需要實時更新用戶時,您應該使用useCallback

  const updateUser = useCallback(async () => {
    const loadedUser = await loadUser();
    setUser(loadedUser); 
  }, []);

  useEffect(() => {
    updateUser();
  }, [updateUser]);

嘗試這樣的事情:

// Assuming your loadUser() functions is set like the line below
const loadedUser = {userID: '513216351354'};


const Index = () => {

function restore(){
  console.log("Loaded user is " + loadedUser.userID);       // Loaded user is 513216351354
  setUser(loadedUser.userID); 
  console.log("User is " + user);                          // User is 513216351354
};

useEffect(() => {
  restore();
}, [])

return (<></>);
}

export default Index;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM