Reputation: 158
I'm banging my head trying to work around one annoying problem:
I have a parent component and a child one. The child has absolute positioning and dynamic height. I need to calculate the parent's margin depending on the child's height. I tried to do something like
const Parent = () => {
const childRef = useRef(null);
return (
<Child saveRef={ref} />
);
const Child = ({saveRef}) => (<div ref={saveRef}> </div>);
But the problem is that Parent component doesn't rerender when Ref is fulfilled. How can I rerender Parent component after Ref is received?
Thanks in advance for any help and advice.
Upvotes: 2
Views: 2932
Reputation: 282040
Write an effect in parent that run on intial mount. This effect will run after the ref is initialized and child in rendered. After this maintain a state in parent which is the margin that you need to calculate and once you calculate the margin update the state
const Parent = () => {
const childRef = useRef(null);
const [margin, updateMargin] = useState(0);
useEffect(() => {
// calculate margin. Let call it margin
updateMargin(margin);
}, []);
return (
<Child saveRef={ref} />
);
const Child = ({saveRef}) => (<div ref={saveRef}> </div>);
EDIT: In order to update on window resize, you need to add an event listener on window resize and recalculate height
const Parent = () => {
const childRef = useRef(null);
const [margin, updateMargin] = useState(0);
useEffect(() => {
window.addEventListener('resize', handleResize);
() => {
window.removeEventListener('resize', handleResize);
}
}, []);
const handleResize = () => {
// use ref, calcualte margin and update
}
return (
<Child saveRef={ref} />
);
Upvotes: 3
Reputation: 1701
You can pass a function as prop to the child from parent, and call that function when you need to re-render the parent. Changing a state would trigger a render. So in the function you can just Change a state.
class Parent extends React.Component{
state = {ref : null}
handleRef = ref => {
this.setState({ ref });
// your add you method for changing margin
}
render(){
return <Child ref={this.state.ref} handleRefChange={this.handleRef} />
}
}
Store the ref in Parent component and call the handleRefChange from Child component to update it.
Upvotes: 0