import { useEffect, useState } from "react";
import { v4 as uuidv4 } from 'uuid';

interface Item {
  id: string,
  value: number
}

function App() {
  const [list, setList] = useState<Item[]>([]);

  useEffect(() => {
    console.log(list);
  }, [list])

  function createItem() {
    const id = uuidv4();
    setList([...list, { id: id, value: 1 }]);
    return id;
  }

  function updateItem(index: number, value: number) {
    var newArray = [...list];
    newArray[index].value = value;
    setList(newArray);
  }

  async function process() {
    const id = createItem()
    const index = list.findIndex(item => item.id === id);

    // Error starts here because list is empty (?) 

    await new Promise((resolve) => setTimeout(resolve, Math.floor(Math.random() * 10000)));
    updateItem(index, 2);
    await new Promise((resolve) => setTimeout(resolve, Math.floor(Math.random() * 10000)));
    updateItem(index, 3)
    await new Promise((resolve) => setTimeout(resolve, Math.floor(Math.random() * 10000)));
    updateItem(index, 4)
    await new Promise((resolve) => setTimeout(resolve, Math.floor(Math.random() * 10000)));
    updateItem(index, 5)
    await new Promise((resolve) => setTimeout(resolve, Math.floor(Math.random() * 10000)));
  }

  return (
    <div className="App">
      <button onClick={() => {
        process();
      }}>Create</button>
      {list.map((item) => {
        return <p key={item.id}>{item.value}</p>
      })}
    </div>
  );
}

export default App;

我试图创建一个有状态数组,但所有数组元素都应该分别更新自己的状态.

假设:

但当我使用上面的代码时,它在try 查找索引之后就出现了错误.有一段时间,它正在工作,但由于[…列表,项]的原因,项正在覆盖彼此的状态.这可能是因为以前创建的不知道新的.

我完全糊涂了.我只想有一个有状态数组,其中所有元素各自更新自己的状态.

一种解决方法是为项目创建一个新组件,并让它存储/更新自己的数据,但我需要在不创建新组件的情况下执行此操作.

推荐答案

我不得不重构你的代码主要是因为以下原因.

在这里:

const id = createItem()
const index = list.findIndex(item => item.id === id);

当你们在createItem中把项目附加到list时,它不会立即出现在你们想要做findIndex的列表中.

现在,无论您在哪里使用setState,最好使用函数形式,以访问以前的状态.

判断代码:

export default function App() {
  const [list, setList] = React.useState([]);

  React.useEffect(() => {
    console.log(list);
  }, [list]);

  function createItem() {
    const id = uuidv4();
    setList((ps) => [...ps, { id, value: 1 }]);
    return id;
  }

  function updateItem(id, value) {
    setList((ps) => ps.map((x) => (x.id === id ? { ...x, value } : x)));
  }

  async function process() {
    const id = createItem();

    for (let i = 2; i <= 5; i++) {
      await new Promise((resolve) =>
        setTimeout(resolve, Math.floor(Math.random() * 10000))
      );
      updateItem(id, i);
    }
  }

  return (
    <div className="App">
      <button
        onClick={() => {
          process();
        }}
      >
        Create
      </button>
      {list.map((item) => {
        return <p key={item.id}>{item.value}</p>;
      })}
    </div>
  );
}

Javascript相关问答推荐

有条件的悲剧

如何解决CORS政策的问题

Next.js(react)使用moment或不使用日期和时间格式

如何使用JavaScript将文本插入空div

如何为我的astro页面中的相同组件自动创建不同的内容?

更改JSON中使用AJAX返回的图像的路径

在Matter.js中添加从点A到另一个约束的约束

扩展类型的联合被解析为基类型

如何在JAVASCRIPT中临时删除eventListener?

为什么云存储中的文件不能公开使用?

当代码另有说明时,随机放置的圆圈有时会从画布上消失

MongoDB受困于太多的数据

如何访问此数组中的值?

如何在一个对象Java脚本中获取不同键的重复值?

在Vercel中部署Next.js项目时获取`ReferenceError:未定义文档`

如何在Java脚本中对数据进行签名,并在PHP中验证签名?

react -原生向量-图标笔划宽度

如何找到带有特定文本和测试ID的div?

无法使用Redux异步函数读取未定义的useEffect钩子的属性';map';

react :图表负片区域不同 colored颜色