Type 'Dispatch<SetStateAction<any[]>>' is not assignable to type '(values?: string) => void'
Asked Answered
S

4

14

I'm very new to typescipt and trying to make a basic pin-input page. Sandbox link for my code . Although it is working, I'm getting this error for onChange function at line 10:

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)

I'm importing react-hook-pin-input and I'm unable to find any demos to use onChange in ts. Please help me re-write onChange such that valueE becomes the value that is being entered. Source for react-hook-pin-input can be found here - https://github.com/elevensky/react-hook-pin-input

Standice answered 28/10, 2020 at 12:38 Comment(0)
E
16

Notice that onChange is of type (values?: string) => void and you passing setValueE which is of type React.Dispatch<React.SetStateAction<string[]>> which means setValueE accepts string[] and you passing a string type on writing onChange={setValueE}.

It works for you only by mistake, because you init valueE with string but then change it to string type, for it to work as expected do something like:

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

Endostosis answered 28/10, 2020 at 12:53 Comment(1)
This solution worked for me, with a little different was that I add "as string[]" after ...string, ====> [...string as string[]]Foreandafter
O
2

Note that you may see a similar error if you use a normal input component with useState. The cause is that the onChange property expects a function that takes an event, while the actual value of the input field would be event.target.value.

So instead of directly writing onChange={setName}, you would need to do something like:

  const [name, setName] = useState('');

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

Then it should work.

Octan answered 30/1, 2023 at 19:56 Comment(0)
S
1

I faced this issue, same problem, I had

Try assign the state using the following method, this works for me ,hope will help others

let code: IUser;
let setCode: any;
[code, setCode] = useState('');
Seedcase answered 17/12, 2022 at 4:1 Comment(2)
You shouldn't say I have this problem, and etc. Your answer should explain in detailNones
The empty quotes in useState() did it for me. Thanks!Eulaliaeulaliah
A
0

I faced this issue, almost like your problem, I had

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

Typescript didn't appreciate it, the type of the dispatcher and the eventHandler were not the same.

Type 'Dispatch<SetStateAction>' is not assignable to type 'ChangeEventHandler<HTMLInputElement | HTMLTextAreaElement>'

Then I came up with this wrapper function, which fixes the problem.

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)} />
Afield answered 28/4, 2022 at 6:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.