I have a component that has some props defined like this. The prop in this case is a function that allows us to pass data up into the parent or calling function
type compProps = {
liftableData: (data: IData[] | undefined | false) => void
}
export const BasicComponent = (props: compProps) => {
const { liftableData } = props
// .... more code here
return <div>Some output</div>
}
Then when I use BasicComponent like this
const [someState, setSomeState] = useState<string>('')
const memodData = useMemo((liftableData: IData[] | undefined | false) => {
setSomeState(liftableData)
}, [])
<BasicComponent liftableData={memodData} />
But typescript gives me this error and I have tried all sorts to fix it with no success
Type 'void' is not assignable to type '(liftableData: false | IData[] | undefined) => void'.
How do I setup the memoized function to pass down as a prop ?How do I get rid of the error ?
CodePudding user response:
That's because useMemo
is used for variables.
memodData
will be the result of the useMemo handler you passed: here (liftableData: IData[] | undefined | false) => { setSomeState(liftableData) }
doesn't return anything => memodData
is void
You should instead use useCallback
to got a function:
const memodData = useCallback((liftableData: IData[] | undefined | false) => {
setSomeState(liftableData)
}, [])
CodePudding user response:
Let's take a look on useMemo
type signature:
function useMemo<T>(factory: () => T, deps: DependencyList | undefined): T
First argument of useMemo
is expected to be a function without arguments whereas you are trying to provide a function with arguments.
See this example:
let foo = () => { }
let bar = (arg: number) => {
arg.toExponential()
}
foo = bar // error, fn with args is not assignable to fn without args
bar = foo
const withCallback = (fn: () => void) => { }
withCallback(bar) // expected error
Why do you have this error ? Imagine that there is no error when you are trying to assign bar
to foo
.
let foo = () => { }
let bar = (arg: number) => {
arg.toExponential()
}
// @ts-ignore
foo = bar
foo()
You have a runtime error because it is unsafe operation.
Lets go back to your example, in order to provide some arguments to useMemo
, you should provide them as a second argument of useMemo
like here:
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
Please see docs