【问题标题】:How to add item to immutable array in React setState in Typescript?如何在 Typescript 的 React setState 中将项目添加到不可变数组?
【发布时间】:2020-02-17 15:49:35
【问题描述】:

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

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

【问题讨论】:

    标签: reactjs typescript immutability


    【解决方案1】:

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

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

    【讨论】:

    • 我懂了。我仍然收到以下错误:Argument of type '(prevState: MainState) => any[]' is not assignable to parameter of type 'SetStateAction<MainState>. Type '(prevState:MainState) => any[]' is not assignable to type '(prevState: MainState) => MainState'. Property 'list' is missing in type 'any[]' but required in type MainState
    • 那么这将解决部分问题:setClasses((prevState): MainState => ({ list: [...prevState.list, CLASS] }));。但随后在返回箭头函数的列表中,我再次收到Type 'number' is not assignable to type '0'
    【解决方案2】:

    从您提供的文档中:

    concat() 方法用于合并两个或多个数组

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

    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>
    }
    

    【讨论】:

    • return { list }; 上接收消息:Type 'never[]' is not assignable tot type 'readonly[]'. Types of property 'length' are incompatible. Type 'number' is not assignable to type '0'.
    • 更新的答案,您的状态定义中没有数组类型
    猜你喜欢
    • 1970-01-01
    • 2016-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-07
    • 2019-05-10
    • 1970-01-01
    相关资源
    最近更新 更多