“Dispatch<SetStateAction<any[]>>”类型无法分配给“(values?: string) => void”类型。

13
我对Typescript非常陌生,正在尝试制作一个基本的PIN输入页面。我的代码沙盒链接是这里。虽然它能工作,但是在第10行的onChange函数中,我遇到了以下错误:

Type 'Dispatch<SetStateAction<any[]>>' is not assignable to type '(values?: string) => void'. Types of parameters 'value' and 'values' are incompatible. Type 'string' is not assignable to type 'SetStateAction<any[]>'.ts(2322)

我正在导入react-hook-pin-input,但无法找到任何使用ts的onChange演示。请帮我重写onChange,使valueE成为正在输入的值。 react-hook-pin-input的源代码可以在这里找到。
4个回答

14

请注意,onChange 的类型为 (values?: string) => void,而您正在传递 setValueE,它的类型为 React.Dispatch<React.SetStateAction<string[]>>,这意味着 setValueE 接受 string[] 参数,但是您在编写 onChange={setValueE} 时却传递了一个 string 类型。

这只是因为您最初使用字符串初始化了 valueE,然后将其更改为 string 类型,所以这种方式偶然起作用。要使其按预期工作,请执行以下操作:

export default function App() {
  const [valueE, setValueE] = useState<string[]>([]);
  return (
    <div className="App">
      <h1>验证码</h1>
      <PinInput
        fields={4}
        values={valueE}
        onChange={(string) => setValueE([...string])}
      />
      <div> {valueE} </div>
    </div>
  );
}

Edit blissful-resonance-v3lwz


1
请注意,如果您使用普通的input组件和useState,可能会看到类似的错误。原因是onChange属性期望一个接受event参数的函数,而实际输入字段的值应该是event.target.value
因此,您需要像这样做,而不是直接编写onChange={setName}
  const [name, setName] = useState('');

  return(
                   <input
                      type="text"
                      value={name}
                      onChange={(event) => {
                        setName(event.target.value);
                      }}
                    />
    )

那么它应该可以工作。


0

我遇到了这个问题,几乎和你的问题一样,我曾经

const [code, setCode] = useState('');
<TextField
   label="code"
   value={code}
   onChange={setCode}
/>

Typescript不赞同,调度程序(dispatcher)和事件处理程序(eventHandler)的类型不同。

类型 'Dispatch<SetStateAction>' 不能分配给类型 'ChangeEventHandler<HTMLInputElement | HTMLTextAreaElement>'

然后我想到了这个包装函数(wrapper function),解决了这个问题。

function withEvent(func: Function): React.ChangeEventHandler<any> {
  return (event: React.ChangeEvent<any>) => {
    const { target } = event;
    func(target.value);
  };
}

// then wrap your function with it
<TextField label="code" value={code} onChange={withEvent(setCode)} />

0
我遇到了这个问题,和你一样的问题。
尝试使用以下方法分配状态,这对我有用,希望能帮助其他人。
let code: IUser;
let setCode: any;
[code, setCode] = useState('');

1
你不应该说“我有这个问题”等等。你的回答应该详细解释。 - Parisa.H.R

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接