I need to access the location of a child component. For what I understand, to access the child properties, I need to use useImperativeHandle
to add the child API to its ref. Moreover, I need to use forwardRef
to transmit the reference from the parent to the child. So I did this:
const Text = React.forwardRef(({ onClick }, ref) => {
const componentAPI = {};
componentAPI.getLocation = () => {
return ref.current.getBoundingClientRect ? ref.current.getBoundingClientRect() : 'nope'
};
React.useImperativeHandle(ref, () => componentAPI);
return (<button onClick={onClick} ref={ref}>Press Me</button>);
});
Text.displayName = "Text";
const App = () => {
const ref = React.createRef();
const [value, setValue] = React.useState(null)
return (<div>
<Text onClick={() => setValue(ref.current.getLocation())} ref={ref} />
<div>Value: {JSON.stringify(value)}</div>
</div>);
};
ReactDOM.render(<App />, document.querySelector("#app"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="app"></div>
As you can see, the ref doesn't have the getBoundingClientRect
property, but if I do this it will work as expected:
const App = () => {
const ref = React.createRef();
const [value, setValue] = React.useState(null)
return (<div>
<button ref={ref} onClick={() => setValue(ref.current.getBoundingClientRect()) } ref={ref}>Press Me</button>
<div>Value: {JSON.stringify(value)}</div>
</div>);
};
ReactDOM.render(<App />, document.querySelector("#app"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="app"></div>
So what is wrong with my understanding of useImperativeHanedle
and forwardRef
?