Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass a setter hook to a child component and satisfy TypeScript

I want to pass a setter hook (setValuesList) from the parent (App.tsx) to the childcomponent (AddNumber.tsx)

I defined the hook in the parent component like this:

const [valuesList, setValuesList] = useState<number[]>([]);

And I want to pass the hook to the childcomponent like this:

<AddNumber valuesList={valuesList} setValuesList={setValuesList} />

However I get a Typescript error:

(JSX attribute) AppProps.setValuesList: (num: number) => void
Type 'Dispatch<SetStateAction<number[]>>' is not assignable to type '(num: number) => void'.
  Types of parameters 'value' and 'num' are incompatible.
    Type 'number' is not assignable to type 'SetStateAction<number[]>'.ts(2322)
AddNumber.tsx(5, 3): The expected type comes from property 'setValuesList' which is declared here on type 'IntrinsicAttributes & AppProps'

In the childcomponent I am defining an interface for the props like this:

interface AppProps {
  valuesList: number[];
  setValuesList: (num: number) => void;
}

Does anyone see what I am doing wrong here?

my repository is at: https://github.com/acandael/number-list

Thanks for your help,

Anthony

like image 848
Toontje Avatar asked Jul 16 '20 15:07

Toontje


People also ask

How do you pass a function from parent to child in TypeScript?

To pass a function as props in React TypeScript: Define a type for the function property in the component's interface. Define the function in the parent component. Pass the function as a prop to the child component.

How do you pass data from parent to child in react hooks?

First, you'll need to create two components, one parent and one child. Next, you'll import the child component in the parent component and return it. Then you'll create a function and a button to trigger that function. Also, you'll create a state using the useState Hook to manage the data.

What is the type of props children in TypeScript?

Children is a special prop that allows us to pass in any type of element. It could be a number, a string, a boolean, an array of elements or even another component.

What is hook component?

Hooks allow function components to have access to state and other React features. Because of this, class components are generally no longer needed. Although Hooks generally replace class components, there are no plans to remove classes from React.


1 Answers

This the type definition for useState hook

function useState<S>(initialState: S | (() => S)): [S, Dispatch<SetStateAction<S>>];

So if you pass the type number[] for the state value when calling useState the type for the setter function will be React.Dispatch<SetStateAction<number[]>>

import { SetStateAction } from 'react';

// this interface will satisfy if you want to pass setValuesList directly
interface AppProps {
  valuesList: number[];
  setValuesList: React.Dispatch<SetStateAction<number[]>>;
 
  // setValuesList: (val: number[]) => void  will also satisfy, but it is
  // better to be explict and pass React.Dispatch<SetStateAction<number[]>>
}

if you don't want to modify the interface you can create and pass another function.

// you don't need to modify the interface if you take this approach -
// the interface already satisfies the type required in this case
const updateValue = (num: number) => {
 setValuesList(prev => prev.concat(num))
}

<AddNumber valuesList={valuesList} setValuesList={updateValue} />
like image 137
subashMahapatra Avatar answered Oct 19 '22 17:10

subashMahapatra