Why does the following code:
import React, {Dispatch, SetStateAction, useState} from 'react'
type Fn = () => void
export const Component = () => {
const [fn, setFn]: [Fn, Dispatch<SetStateAction<Fn>>] = useState(() => {})
return <p>{`${typeof fn}, ${typeof setFn}`}</p>
}
produce the following Typescript error:
Type '[void, Dispatch<SetStateAction>]' is not assignable to type '[Fn, Dispatch<SetStateAction>]'.
Type at position 0 in source is not compatible with type at position 0 in target.
Type 'void' is not assignable to type 'Fn'.ts(2322)
const fn: Fn
?
You can see this in action yourself
This is happening because, if a function is passed to useState
, this is taken as a callback that React runs to determine the initial state. It's a way of not calling expensive processes that determine the initial state of every render.
If you want the state to be a function, you need to nest it inside another function.
const [fn, setFn] = useState(() => () => {})
No need to explicitly note the type - TypeScript can infer it automatically.