Warum müssen Sie React useState in Form von Funktionsupdates verwenden?
P粉155551728
P粉155551728 2023-10-22 15:37:50
0
2
747

Ich habe die React Hook-Dokumentation zu Funktionsaktualisierungen gelesen und mir das folgende Zitat angesehen:

Die Schaltflächen „+“ und „-“ verwenden aufgrund von Aktualisierungen eine funktionale Form Werte basieren auf vorherigen Werten

Aber ich verstehe nicht, wozu Funktionsaktualisierungen erforderlich sind und was der Unterschied zwischen ihnen und der direkten Verwendung des alten Zustands zur Berechnung des neuen Zustands ist.

Warum benötigt React für die Updater-Funktion von State Hook ein funktionales Update-Formular? Gibt es Beispiele, bei denen wir den Unterschied deutlich erkennen können (und die Verwendung einer direkten Aktualisierung daher zu einem Fehler führen würde)?

Zum Beispiel, wenn ich dieses Beispiel aus der Dokumentation ändere

function Counter({initialCount}) {
  const [count, setCount] = useState(initialCount);
  return (
    <>
      Count: {count}
      <button onClick={() => setCount(initialCount)}>Reset</button>
      <button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
      <button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
    </>
  );
}

Direkt aktualisierencount:

function Counter({initialCount}) {
  const [count, setCount] = useState(initialCount);
  return (
    <>
      Count: {count}
      <button onClick={() => setCount(initialCount)}>Reset</button>
      <button onClick={() => setCount(count + 1)}>+</button>
      <button onClick={() => setCount(count - 1)}>-</button>
    </>
  );
}

Ich sehe keinen Unterschied im Verhalten und kann mir keine Situation vorstellen, in der die Zählung nicht aktualisiert wird (oder nicht aktuell ist). Denn jedes Mal, wenn sich die Anzahl ändert, wird ein neuer Abschluss von onClick aufgerufen, der das Neueste erfasst onClick 的新闭包,捕获最新的 count.

P粉155551728
P粉155551728

Antworte allen(2)
P粉818125805

我最近偶然发现了这个需求。例如,假设您有一个组件,它用一定数量的元素填充一个数组,并且能够根据某些用户操作附加到该数组(就像在我的例子中,我一次加载一个提要 10 个项目,因为用户不断向下滚动屏幕。代码看起来有点像这样:

function Stream() {
  const [feedItems, setFeedItems] = useState([]);
  const { fetching, error, data, run } = useQuery(SOME_QUERY, vars);

  useEffect(() => {
    if (data) {
      setFeedItems([...feedItems, ...data.items]);
    }
  }, [data]);     // <---- this breaks the rules of hooks, missing feedItems

...
<button onClick={()=>run()}>get more</button>
...

显然,您不能只将 feedItems 添加到 useEffect 挂钩中的依赖项列表中,因为您要在其中调用 setFeedItems,因此您会陷入循环。

功能更新来拯救:

useEffect(() => {
    if (data) {
      setFeedItems(prevItems => [...prevItems, ...data.items]);
    }
  }, [data]);     //  <--- all good now
P粉457445858

React 中状态更新是异步的。因此,当您下次更新时,count 中可能会有旧值。例如,比较这两个代码示例的结果:

function Counter({initialCount}) {
  const [count, setCount] = useState(initialCount);
  return (
    <>
      Count: {count}
      <button onClick={() => setCount(initialCount)}>Reset</button>
      <button onClick={() => {
        setCount(prevCount => prevCount + 1); 
        setCount(prevCount => prevCount + 1)}
      }>+</button>
    </>
  );
}

function Counter({initialCount}) {
  const [count, setCount] = useState(initialCount);
  return (
    <>
      Count: {count}
      <button onClick={() => setCount(initialCount)}>Reset</button>
      <button onClick={() => {
        setCount(count + 1); 
        setCount(count + 1)}
      }>+</button>
    </>
  );
}
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage