简体   繁体   中英

How to access parent ref from child

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?

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"));

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM