簡體   English   中英

State 未從 useEffect 掛鈎更新

[英]State not updating from useEffect hook

出於某種原因,當我從 useEffect 掛鈎更新我的 state 時,它沒有持續存在。 我希望我的用戶列表會不斷增長,但我只看到一個用戶。 為什么用戶沒有增長?

import { useState, useEffect } from "react";

interface IUser {
  name: {
    first: string;
    last: string;
  };
  picture: {
    thumbnail: string;
  };
}

function App() {
  const [users, setUsers] = useState<IUser[]>([]);

  const getUserName = (user: IUser): string => {
    if (!user) return "";

    return `${user.name.first} ${user.name.last}`;
  };

  const getThumbnail = (user: IUser): string => {
    if (!user) return "";

    return user.picture.thumbnail;
  };

  useEffect(() => {
    setInterval(() => {
      fetch("https://randomuser.me/api")
        .then((res) => res.json())
        .then((json) => {
          let newusers = [...users, json.results[0]];
          setUsers(newusers);
        })
        .catch((err) => {
          console.log(err);
        });
    }, 3000);
  }, []);

  return (
    <div className="App">
      {users?.map((user, idx) => (
        <div key={idx}>
          <h2>{getUserName(user)}</h2>
          <img src={getThumbnail(user)} />
        </div>
      ))}
    </div>
  );
}

export default App;

這是一個演示問題的codesandbox https://codesandbox.io/s/react-typescript-forked-5h3553?file=/src/App.tsx:0-1054

問題來自setInterval的使用。 當它被定義時,它會創建一個閉包,其中包含變量users的當前值,當然它以[]開頭。 所以每次調用間隔時,它都使用它在實例化時的值。

幸運的是,對 setState 的調用傳遞了前面 state 的一個參數,您可以使用它來快速解決您的問題:

.then((json) => {
  setUsers((prev) => [...prev, json.results[0]]);
})

您需要使用從 useState 鈎子返回的方法來更新數組。

這是解決方案:

let newuser = json.results[0];
setUsers(prev => [...prev, newuser]);

代替:

let newusers = [...users, json.results[0]];
setUsers(newusers);

只需像這樣直接更新setUsers

setUsers(prevState => […prevState, json.results[0]]);

暫無
暫無

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

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