如何在 Typescript 的 React setState 中将项目添加到不可变数组?

How to add item to immutable array in React setState in Typescript?

我想使用不可变数组来处理状态。并向此列表添加一个项目。

interface MainState {
  list: readonly []; // define immutable array
}

const Component: React.FC = () => {
  // by default use the immutable array with type
  const [classes, setClasses] = useState({ list: [] } as MainState);

  useEffect(() => {
    if (data) {
      data.forEach((thing) => {
        setClasses(prevState => {
          //
          // Call signature return types '{ list: never[]; }' and 'MainState' are incompatible.
          // The types of 'list.length' are incompatible between these types.
          // Type 'number' is not assignable to type '0'.  TS2345
          //
          const list = prevState.list.concat(thing);
          return { list };
        });
      });
    }
  });
// ...

}

我虽然使用 concat 会起作用,因为它 returns a new array

最简单、最容易接受的方法:

const list = [...prevState.list, thing];

根据您提供的文档:

The concat() method is used to merge two or more arrays

所以你需要传递数组,而不是元素给这个函数,我想这会起作用:

const list = prevState.list.concat([thing]);

我还看到你的代码正在遍历新数组并一个一个地传递元素,你为什么不连接整个数组?

    if (data) {
        setClasses(prevState => {
          const list = prevState.list.concat(data);
          // or list = [...prevState.list, ...data];
          return { list };
        });
    }

此外,我认为您错过了 MainState 中的数组类型,至少将其更新为 any 类型,这里是 number 类型的完整示例:

interface MainState {
  list: readonly number[];
}

const data = [1, 2, 3]

const Component: React.FC = () => {

  const [classes, setClasses] = useState({ list: [] } as MainState);

  useEffect(() => {
    if (data) {
      setClasses(prevState => ({ list: [...prevState.list, ...data]}));
    }
  });

  return <div>{classes}</div>
}