Reputation: 183
I have some problem to pass the ref to child element in JSX. Please, see the following:
import React from "react";
import ReactDOM from "react-dom";
class App extends React.Component {
render() {
return (
<div id="parent" ref={element => (this.parentRef = element)}>
<canvas id="child" width={this.parentRef.offsetWidth} />
</div>
);
}
}
ReactDOM.render(document.getElementById("app"), <App />);
I want to access #parent
width from #child
. How it is possible?
Upvotes: 3
Views: 23810
Reputation: 1479
This is where React starts tying itself in knots. I've got a simple answer below (but I wasted too much time working this out)
My solution - just use javascript - specifically ".parentElement"
In the child element - you can get a reference to the child and from that you can get its parent. eg:
// Child component
const childRef = useRef(null);
<div ref={childRef}> ..... </div>
Then to get the parent element within the child just use:
childRef.current.parentElement
Upvotes: 0
Reputation: 1052
This is very late, but I have a solution using the latest React hooks and functional components for future viewers. Due to the way how refs work, they do not cause a re-render on value change. However, mozilla added something called ResizeObserver: https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver , which watches components for resize.
import React, { useRef, useEffect, useState } from "react";
import ResizeObserver from "resize-observer-polyfill";
export default function App() {
const parentRef = useRef(null);
const [width, setWidth] = useState(0);
useEffect(() => {
const ro = new ResizeObserver((entries) => {
entries.forEach((entry) => setWidth(entry.contentRect.width));
});
ro.observe(parentRef.current);
return () => ro.disconnect();
}, []);
return (
<div ref={parentRef}>
<div> {width} </div>
</div>
);
}
code in action: https://codesandbox.io/s/reverent-galileo-q7np5?file=/src/App.js
Upvotes: 2
Reputation: 77
In your particular example you're just getting width of an element and passing it to another element. If you're using latest react version you should checkout new ref's api (https://reactjs.org/docs/refs-and-the-dom.html) And your example will look something like that
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
width: 0
};
this.parentRef = React.createRef();
}
componentDidMount() {
window.addEventListener("resize", this.onResize);
this.onResize();
}
componentWillUnmount() {
window.removeEventListener("resize", this.onResize);
}
onResize = () => {
this.setState({
width: this.getParentSize()
});
};
getParentSize() {
return (this.parentRef.current && this.parentRef.current.offsetWidth) || 0;
}
render() {
return (
<div id="parent" ref={this.parentRef}>
<canvas
id="child"
width={this.getParentSize()}
style={{ background: "red" }}
/>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
Upvotes: 0