【问题标题】:What type to specify for event handlers tied to multiple fields?为绑定到多个字段的事件处理程序指定什么类型?
【发布时间】:2021-07-08 13:03:37
【问题描述】:

我有一个基于this tutorial 的带有动态字段的 React 表单。它需要修改为与 TypeScript 兼容。我收到此错误:

“元素隐含地具有'any'类型,因为'any'类型的表达式不能用于索引类型'{ makeModel: string; year: string; }'。”

 const handleCarChange = (e: any, index: number) => {
    const { name, value } = e.target;
    const list = [...carList];
    list[index][name] = value;  // TODO fix this typescript error
    setCarList(list);
  };

【问题讨论】:

  • 分享carList数组
  • 对于事件,你可以从SyntheticEvent输入React

标签: reactjs typescript


【解决方案1】:

对于使用带有点击处理程序的类型,您可以尝试使用来自React 的 MouseEvent。不确定这是否可以解决打字稿错误。看起来不一样。

import { MouseEvent } from 'react';

const handleCarChange = (e: MouseEvent, index: number) => {
   const { name, value } = e.target;
   const list = [...carList];
   list[index][name] = value;  // TODO fix this typescript error
   setCarList(list);
};

进一步阅读。 https://fettblog.eu/typescript-react/events/

【讨论】:

    【解决方案2】:

    这个教程很糟糕。这只是我的意见。

    为什么?

    首先,const list = [...carList]; 这一行没有任何意义。

    这里,教程的作者还是修改了数组

    list[index][name] = value;
    

    考虑下一个例子:

    const list = [{ name: 1 }]
    const newList = [...list]
    newList[0]["name"] = 2
    
    list // [{name: 2}]
    

    你不应该改变状态。这行[...list] 只创建浅拷贝。它只是对整个数组的新引用,但数组中的每个元素仍然具有相同的引用。

    让我们回到你的问题。

    
    type Fn = (args: any) => any
    
    type ChangeHandler = ChangeEventHandler<HTMLInputElement>
    
    type WithIndex<T extends Fn> = (e: Parameters<T>[0], index: number) => void
    
    const Component = () => {
      const [inputList, setInputList] = useState<State>([{ firstName: "", lastName: "" }]);
    
      const handleCarChange: WithIndex<ChangeHandler> = (e, index) => {
        const { name, value } = e.target;
    
        const newList = inputList.map((elem: Entity, i: number) =>
          i === index ? {
            ...elem,
            [name]: value
          } : elem)
    
        setInputList(newList);
      };
    
      return (
        <input
          onChange={e => handleCarChange(e, 0)}
        />
      )
    }
    

    请记住,对于任何鼠标处理程序,您始终可以使用内置类型,例如 ChangeEventHandler

    Playground

    如果你想更新你的状态请参考官方reduxpatterns

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多