Reputation: 3805
I have been using React from few years and today I encouraged a very unique use case which I need to tackle. I need to make my own ref. there are certain libraries that do it and I don't yet how they do it.
So basically what I need to do is
const ref = useRef();
/**
where ref.reset(); will work
*/
<Menu ref={ref}/>
My custom component:
const Menu = () => {
const reset = () => {
setValue(0);
}
return <CustomMenuComponent />
}
So basically I need to expose this method in the parent. I know this can be done via state and should be done that way, I have just added a minimum use case for my problem. So basically I need to expose some methods in my component, ideally using refs.
Upvotes: 4
Views: 4394
Reputation: 53914
Thats when useImperativeHandle
used.
useImperativeHandle
customizes the instance value that is exposed to parent components when usingref
.
const Menu = React.forwardRef((props, ref) => {
useImperativeHandle(ref, () => ({
reset: () => {
console.log("reset");
}
}));
return <></>;
});
export default function App() {
const ref = useRef();
useEffect(() => {
ref.current.reset();
}, []);
return <Menu ref={ref} />;
}
Upvotes: 15
Reputation: 85062
For that, there's the rarely-needed useImperativeHandle
hook. It lets you specify what external components will get if they pass a ref into your function component:
const Menu = React.forwardRef((props, ref) => {
const [value, setValue] = useState(0);
useImperativeHandle(ref, () => {
return {
reset: () => setValue(0)
}
}, []);
return <CustomMenuComponent />
});
// Usage:
const Example = () => {
const ref = useRef();
useEffect(() => {
ref.current.reset();
}, []);
return <Menu ref={ref} />;
}
You can see more information on this hook here. As they mention in the docs, you should avoid using refs when possible, though you seem to be aware of this as you described yourself as having "a very unique use case".
Upvotes: 3