Reputation: 137
i want to add types to methods passed as props from parent to child component using react and typescript.
below is my code,
function Parent() {
const [isClicked, setIsClicked] = React.useState(false);
return (
<Child setIsClicked={setIsClicked} >
<div> somediv</div>
</Child>
);
}
interface Props {
setIsClicked: any; //instead of any what type should be used here
}
function Child ({setIsClicked, children}: Props) {
return (
<div onClick={setIsClicked}>
{children}
</div>
);
}
As you see from above code, i am using any as type for setIsClicked method. this works. but i know that this is not the right way to do it.
could someone help me with this. thanks.
Upvotes: 0
Views: 413
Reputation: 25790
That's how I would do it:
const Parent: React.FunctionComponent = () => {
const [isClicked, setIsClicked] = React.useState(false);
const handleClick = React.useCallback(() => {
setIsClicked(true)
}, []);
return (
<Child onClick={handleClick}>
<div> somediv</div>
</Child>
);
}
interface Props {
onClick: React.UIEventHandler<HTMLDivElement>
}
const Child: React.FunctionComponent<Props> = ({ onClick, children }) => {
return (
<div onClick={onClick}>{children}</div>
)
}
handleClick
is a generic click handler. No coupling to React hooks. The caller (Parent) can do whatever it chooses when the Child is clicked.handleClick
is memoized thanks to React.useCallback
Upvotes: 1
Reputation: 41893
The setter function accepts a value or a callback function which may complicate things a little bit. What I would suggest is to create a separate function to handle the onclick instead of passing the setter directly. It's more readable and cleaner.
Also remember to use the generic type when using useState
hook.
function Parent() {
const [isClicked, setIsClicked] = React.useState<Boolean>(false);
const handleClick = (value: boolean) => {
setIsClicked(value);
};
return (
<Child setIsClicked={handleClick}>
<div>somediv</div>
</Child>
);
}
interface Props {
setIsClicked: (value: boolean) => void;
}
Upvotes: 1
Reputation: 370679
The most precise type for that a setter function for type T
is:
React.Dispatch<React.SetStateAction<T>>,
So you can do:
setIsClicked: React.Dispatch<React.SetStateAction<Boolean>>
But that's a bit wordy and sometimes requires import boilerplate you don't want. Often, denoting the type as a plain function that accepts the type as an argument is sufficient:
setIsClicked: (newClicked: boolean) => void
Upvotes: 2