React - 在组件中使用 ref 并将其传递给 props 中的父级
React - use ref in component AND pass it to parent in props
更新:我的问题实际上是由于拼写错误造成的——如果您想在子组件和父组件中都使用子元素 ref,则一般方法可以正常工作。
这是一个有效方法的工作示例:
https://codesandbox.io/s/rwj7z7o7oo
原文post:
我正在尝试将 ref 转发给父组件,同时也使子组件(即 class)中的函数可以访问该 ref。目前,我可以成功将 ref 传递给父级,但子级无法再访问该 ref。
class Child extends React.Component {
// Unable to access the forwarded ref here:
componentDidMount() {
console.log(this.props.forwardedRef); // null
}
render() {
return <input type="text" ref={this.props.forwardedRef} />
}
}
// Parent is able to access the ref:
const Parent = () => {
const childRef = useRef(null);
function handleClick() {
console.log(childRef.current); // correctly ref's the input el
}
return (
<Child forwardedRef={childRef} onClick={handleClick} />
);
}
是否有另一种方法可以让我在 Child 和 Parent 中使用 ref?
useRef
returns 类似于实例变量的值 类。在您的情况下,即使您设置了 ref 也不会导致组件呈现,因此子组件的 componentDidUpdate 不会 运行.
此外,您还没有从子组件返回任何内容。
class Child extends React.Component {
// Unable to access the forwarded ref here:
componentDidUpdate(prevProps) {
console.log(this.props.forwardedRef); // null
console.log(prevProps.forwardedRef); // null
}
render() {
return (
<React.Fragment>
<input type="text" ref={this.props.forwardedRef} />
<div>{this.props.count}</div>
<input type="button" onClick={this.props.onClick} value={"Click"} />
</React.Fragment>
);
}
}
// Parent is able to access the ref:
const Parent = () => {
const childRef = useRef(null);
const [count, setCount] = useState(0);
function handleClick() {
console.log(childRef.current); // correctly ref's the input el
setCount(count => count + 1);
}
return <Child forwardedRef={childRef} count={count} onClick={handleClick} />;
};
反应挂钩
不需要在 React hooks 中传递 forwardedRef
。
您可以直接在forwardRef
函数中访问ref
变量:
const Child = React.forwardRef((_props, ref) => {
React.useLayoutEffect(() => {
if (ref.current) {
ref.current.insertAdjacentHTML(
"beforeend",
"<span>Ref works in child</span>"
);
}
}, [ref]);
return (
<div className="child" ref={ref}>
<h2>Child Component</h2>
</div>
);
});
const Parent = () => {
const childRef = React.useRef(null);
React.useLayoutEffect(() => {
if (childRef.current) {
childRef.current.insertAdjacentHTML(
"afterbegin",
"<span>Ref works in parent</span>"
);
}
}, []);
return (
<div className="parent">
<h1>Parent Component</h1>
<Child ref={childRef} />
</div>
);
};
function App() {
return (
<div className="App">
<Parent />
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(
<App />,
rootElement
);
.App {
font-family: sans-serif;
text-align: center;
padding: 1rem;
}
.parent {
border: 1px dashed red;
padding: 1rem;
}
.child {
border: 1px dashed blue;
padding: 1rem;
}
span {
display: block;
padding-top: 0.5rem;
padding-bottom: 0.5rem;
margin: 0.5rem;
color: #777;
border: 1px dashed #999;
}
<div id="root"></div>
<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>
更新:我的问题实际上是由于拼写错误造成的——如果您想在子组件和父组件中都使用子元素 ref,则一般方法可以正常工作。
这是一个有效方法的工作示例: https://codesandbox.io/s/rwj7z7o7oo
原文post:
我正在尝试将 ref 转发给父组件,同时也使子组件(即 class)中的函数可以访问该 ref。目前,我可以成功将 ref 传递给父级,但子级无法再访问该 ref。
class Child extends React.Component {
// Unable to access the forwarded ref here:
componentDidMount() {
console.log(this.props.forwardedRef); // null
}
render() {
return <input type="text" ref={this.props.forwardedRef} />
}
}
// Parent is able to access the ref:
const Parent = () => {
const childRef = useRef(null);
function handleClick() {
console.log(childRef.current); // correctly ref's the input el
}
return (
<Child forwardedRef={childRef} onClick={handleClick} />
);
}
是否有另一种方法可以让我在 Child 和 Parent 中使用 ref?
useRef
returns 类似于实例变量的值 类。在您的情况下,即使您设置了 ref 也不会导致组件呈现,因此子组件的 componentDidUpdate 不会 运行.
此外,您还没有从子组件返回任何内容。
class Child extends React.Component {
// Unable to access the forwarded ref here:
componentDidUpdate(prevProps) {
console.log(this.props.forwardedRef); // null
console.log(prevProps.forwardedRef); // null
}
render() {
return (
<React.Fragment>
<input type="text" ref={this.props.forwardedRef} />
<div>{this.props.count}</div>
<input type="button" onClick={this.props.onClick} value={"Click"} />
</React.Fragment>
);
}
}
// Parent is able to access the ref:
const Parent = () => {
const childRef = useRef(null);
const [count, setCount] = useState(0);
function handleClick() {
console.log(childRef.current); // correctly ref's the input el
setCount(count => count + 1);
}
return <Child forwardedRef={childRef} count={count} onClick={handleClick} />;
};
反应挂钩
不需要在 React hooks 中传递 forwardedRef
。
您可以直接在forwardRef
函数中访问ref
变量:
const Child = React.forwardRef((_props, ref) => {
React.useLayoutEffect(() => {
if (ref.current) {
ref.current.insertAdjacentHTML(
"beforeend",
"<span>Ref works in child</span>"
);
}
}, [ref]);
return (
<div className="child" ref={ref}>
<h2>Child Component</h2>
</div>
);
});
const Parent = () => {
const childRef = React.useRef(null);
React.useLayoutEffect(() => {
if (childRef.current) {
childRef.current.insertAdjacentHTML(
"afterbegin",
"<span>Ref works in parent</span>"
);
}
}, []);
return (
<div className="parent">
<h1>Parent Component</h1>
<Child ref={childRef} />
</div>
);
};
function App() {
return (
<div className="App">
<Parent />
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(
<App />,
rootElement
);
.App {
font-family: sans-serif;
text-align: center;
padding: 1rem;
}
.parent {
border: 1px dashed red;
padding: 1rem;
}
.child {
border: 1px dashed blue;
padding: 1rem;
}
span {
display: block;
padding-top: 0.5rem;
padding-bottom: 0.5rem;
margin: 0.5rem;
color: #777;
border: 1px dashed #999;
}
<div id="root"></div>
<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>