简体   繁体   English

当组件位于数组内时,State 不会从 function 更新

[英]State is not updating from a function when the components are inside an array

Changing state from other components in this case ( Dominator ) is working but when I put those components inside an array and do the same thing the updateCounter function is getting called but it's not updating the counter state.在这种情况下( Dominator )从其他组件更改 state 是有效的,但是当我将这些组件放在一个数组中并做同样的事情时, updateCounter function 被调用,但它没有更新counter Z9ED39E2EA931586B3EZEF558。

import { useEffect, useState } from "react";
import Dominator from "./dominator";
import "./styles.css";

export default function App() {
  const [counter, setCounter] = useState(1);
  const updateCounter = () => {
    console.log("counter lookup: ", counter);
    setCounter(counter + 1);
  };
  const [dominators, setDominators] = useState([
    <Dominator key={0} updateCounter={updateCounter} />
  ]);

  useEffect(() => {
    console.log("counter has changed:", counter)
  }, [counter])
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      {dominators.map((item) => {
        return item;
      })}
    </div>
  );
}

Issue问题

The issue is stale state enclosures in the updateCounter callback.问题是updateCounter回调中的过时 state 机箱。 Each mapped element is receiving a callback with the same value of counter to update from.每个映射元素都在接收一个回调,该回调具有相同的counter值以进行更新。

Storing instantiated React components in state is also anti-pattern and doesn't help the stale state enclosures.在 state 中存储实例化的 React 组件也是反模式,对陈旧的 state 外壳没有帮助。 You should store the data only and render the derived JSX from the data.您应该只存储数据并从数据中呈现派生的 JSX。

Solution解决方案

Use a functional state update to correctly update from the previous state instead of the state the callback/state update was enclosed in.使用功能性 state 更新以正确更新之前的 state 而不是包含回调/状态更新的 state。

Store only the data in the dominators state and map it to the Dominator component.仅将dominators器 state 和 map 中的数据存储到Dominator器组件。

export default function App() {
  const [counter, setCounter] = useState(1);

  const updateCounter = () => {
    setCounter(counter => counter + 1);
  };

  const [dominators, setDominators] = useState([0]);

  useEffect(() => {
    console.log("counter has changed:", counter);
  }, [counter]);

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      {dominators.map((item) => (
        <Dominator key={item} updateCounter={updateCounter} />
      ))}
    </div>
  );
}

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

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