Reputation: 46
I missed more information about this type of use in React Docs.
I've seen it in some codes and it doesn't sound cool for me.
I made an example here: https://codesandbox.io/s/goofy-chaplygin-5bxwp
useImperativeHandle: https://reactjs.org/docs/hooks-reference.html#useimperativehandle
const CheckItem = forwardRef(({ children, ...rest }, ref) => {
const [checked, setCheck] = useState(false);
useImperativeHandle(ref, () => ({
toggle: () => {
setCheck(checked => !checked);
}
}));
return (
<div
{...rest}
style={{ textDecoration: checked ? "line-through" : "none" }}
>
{children}
</div>
);
});
Upvotes: 1
Views: 1462
Reputation: 85102
I would definitely recommend against using refs for this. This situation can use the standard react approach: lift state up, and pass down props.
export default function App() {
const [checked, setCheck] = useState(false);
return (
<div className="App">
<h1>Imperative Handles</h1>
<CheckItem value={checked}>
<h2>Item 1</h2>
</CheckItem>
<button onClick={() => setCheck(checked => !checked)}>
Toggle item 1
</button>
</div>
);
}
// ....
const CheckItem = ({ checked, children, ...rest }) => {
return (
<div
{...rest}
style={{ textDecoration: checked ? "line-through" : "none" }}
>
{children}
</div>
);
};
Upvotes: 4
Reputation: 11181
In the React document (https://reactjs.org/docs/hooks-reference.html#useimperativehandle), it stats that:
useImperativeHandle customizes the instance value that is exposed to parent components when using ref. As always, imperative code using refs should be avoided in most cases. useImperativeHandle should be used with forwardRef.
In your case, you can expose the checked
as property. There is no reason to use useImperativeHandle
Upvotes: 1