推荐用于 16.3 之前的 React 版本
如果无法避免,从React docs 中提取的建议模式将是:
import React, { Component } from 'react';
const Child = ({ setRef }) => <input type="text" ref={setRef} />;
class Parent extends Component {
constructor(props) {
super(props);
this.setRef = this.setRef.bind(this);
}
componentDidMount() {
// Calling a function on the Child DOM element
this.childRef.focus();
}
setRef(input) {
this.childRef = input;
}
render() {
return <Child setRef={this.setRef} />
}
}
Parent 将函数作为绑定到 Parent's this 的 prop 转发。当 React 调用 Child's ref prop setRef 时,它会将 Child's ref 分配给 Parent's childRef 属性。
推荐用于 React >= 16.3
Ref 转发是一种可选功能,它允许某些组件获取它们接收到的 ref,并将其进一步向下传递(换句话说,“转发”它)给子级。
我们创建组件,通过React.forwardRef 转发他们的ref。
返回的 Component ref prop 必须与 React.createRef 的返回类型相同。每当 React 挂载 DOM 节点时,使用 React.createRef 创建的 ref 的属性 current 将指向底层 DOM 节点。
import React from "react";
const LibraryButton = React.forwardRef((props, ref) => (
<button ref={ref} {...props}>
FancyButton
</button>
));
class AutoFocus extends React.Component {
constructor(props) {
super(props);
this.childRef = React.createRef();
this.onClick = this.onClick.bind(this);
}
componentDidMount() {
this.childRef.current.focus();
}
onClick() {
console.log("fancy!");
}
render() {
return <LibraryButton onClick={this.onClick} ref={this.childRef} />;
}
}
转发 refs HOC 示例
创建的组件正在将它们的ref 转发到子节点。
function logProps(Component) {
class LogProps extends React.Component {
componentDidUpdate(prevProps) {
console.log('old props:', prevProps);
console.log('new props:', this.props);
}
render() {
const {forwardedRef, ...rest} = this.props;
// Assign the custom prop "forwardedRef" as a ref
return <Component ref={forwardedRef} {...rest} />;
}
}
// Note the second param "ref" provided by React.forwardRef.
// We can pass it along to LogProps as a regular prop, e.g. "forwardedRef"
// And it can then be attached to the Component.
return React.forwardRef((props, ref) => {
return <LogProps {...props} forwardedRef={ref} />;
});
}
请参阅 React 文档中的 Forwarding Refs。