[英]How to access parent ref from child
我在将 ref 传递给 JSX 中的子元素时遇到了一些问题。 请看以下内容:
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 />);
我想从#child
访问#parent
宽度。 怎么可能?
在您的特定示例中,您只是获取元素的宽度并将其传递给另一个元素。 如果您使用的是最新的 React 版本,您应该查看新的 ref 的 api ( https://reactjs.org/docs/refs-and-the-dom.html ) 并且您的示例看起来像这样
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"));
这已经很晚了,但我有一个使用最新的 React 钩子和功能组件的解决方案,供未来的观众使用。 由于 refs 的工作方式,它们不会导致重新渲染值更改。 然而,mozilla 添加了一个叫做 ResizeObserver 的东西:https ://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver ,它监视组件的大小调整。
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>
);
}
实际代码: https : //codesandbox.io/s/reverent-galileo-q7np5?file=/src/App.js
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.