如何在基于类的组件中使用 React.forwardRef?

我正在尝试使用 React.forwardRef,但是遇到了如何让它在基于类的组件(而不是 HOC)中工作的问题。

文档示例使用元素和函数组件,甚至将类包装到高阶组件的函数中。

因此,从 ref.js文件中的 这个开始:

const TextInput = React.forwardRef(
(props, ref) => (<input type="text" placeholder="Hello World" ref={ref} />)
);

而是这样定义它:

class TextInput extends React.Component {
render() {
let { props, ref } = React.forwardRef((props, ref) => ({ props, ref }));
return <input type="text" placeholder="Hello World" ref={ref} />;
}
}

或者

class TextInput extends React.Component {
render() {
return (
React.forwardRef((props, ref) => (<input type="text" placeholder="Hello World" ref={ref} />))
);
}
}

只工作:/

而且,我知道我知道,裁判的反应不是这样的。我正在尝试使用第三方画布库,并希望在单独的组件中添加他们的一些工具,所以我需要事件侦听器,所以我需要生命周期方法。以后可能会有不同的路线,但我想试试这个。

医生说有可能!

转发引用不限于 DOM 组件。您也可以转发类组件实例的引用。

注意。

但是之后他们继续使用 HOC,而不仅仅是类。

88000 次浏览

基本上,这只是一个 HOC 函数。如果你想在课堂上使用它,你可以自己做这件事,并使用常规的道具。

class TextInput extends React.Component {
render() {
<input ref={this.props.forwardRef} />
}
}


const ref = React.createRef();
<TextInput forwardRef={ref} />

这个模式在 styled-components中使用,这里称为 innerRef

class BeautifulInput extends React.Component {
const { innerRef, ...props } = this.props;
render() (
return (
<div style=\{\{backgroundColor: "blue"}}>
<input ref={innerRef} {...props} />
</div>
)
)
}


const BeautifulInputForwardingRef = React.forwardRef((props, ref) => (
<BeautifulInput {...props} innerRef={ref}/>
));


const App = () => (
<BeautifulInputForwardingRef ref={ref => ref && ref.focus()} />
)

您需要使用不同的道具名称来将 ref 转发给类。innerRef在许多库中都是常用的。

始终为 ref使用相同的道具的想法可以通过使用助手代理类导出来实现。

class ElemComponent extends Component {
render() {
return (
<div ref={this.props.innerRef}>
Div has a ref
</div>
)
}
}


export default React.forwardRef((props, ref) => <ElemComponent
innerRef={ref} {...props}
/>);

所以基本上,我们被迫有一个不同的道具,向前裁判,但它可以在枢纽下完成。重要的是,公众使用它作为一个正常的裁判。

如果需要在许多不同的组件中重用此功能,可以将此功能导出到类似于 withForwardingRef的东西

const withForwardingRef = <Props extends {[_: string]: any}>(BaseComponent: React.ReactType<Props>) =>
React.forwardRef((props, ref) => <BaseComponent {...props} forwardedRef={ref} />);


export default withForwardingRef;

用途:

const Comp = ({forwardedRef}) => (
<input ref={forwardedRef} />
)
const EnhanceComponent = withForwardingRef<Props>(Comp);  // Now Comp has a prop called forwardedRef

如果您愿意,这可以通过使用高阶组件来实现:

import React, { forwardRef } from 'react'


const withForwardedRef = Comp => {
const handle = (props, ref) =>
<Comp {...props} forwardedRef={ref} />


const name = Comp.displayName || Comp.name
handle.displayName = `withForwardedRef(${name})`


return forwardRef(handle)
}


export default withForwardedRef

然后在组件文件中:

class Boop extends React.Component {
render() {
const { forwardedRef } = this.props


return (
<div ref={forwardedRef} />
)
}
}


export default withForwardedRef(Boop)

我做了这项工作与测试和发布了一个软件包为此,react-with-forwarded-ref: https://www.npmjs.com/package/react-with-forwarded-ref

如果任何人仍然有困难结合 React.forwardRef()和 HOC 像反应还原 connect()然后这是我如何得到它的工作:

export default connect(mapStateToProps, mapDispatchToProps)(
React.forwardRef((props, ref) => <MyComponent innerRef={ref} {...props} />)
);