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

IT技术 javascript reactjs
2021-04-02 11:09:08

我正在尝试使用 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} />))
    );
  }
}

只工作:/

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

医生说这是可能的!

Ref 转发不仅限于 DOM 组件。您也可以将引用转发到类组件实例。

来自本节注释。

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

5个回答

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

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}
/>);

所以基本上,我们被迫有一个不同的props来转发引用,但它可以在集线器下完成。公众将其用作正常参考很重要。

关于如何在使用 setState 时在 Enzyme 中进行测试的任何见解?
2021-05-31 11:09:08
我得到:不变违规:对象作为 React 子对象无效(发现:对象带有键 {$$typeof, render})。如果您打算渲染一组子项,请改用数组。
2021-06-09 11:09:08
connect或 有withStyles什么问题您应该forwardRef使用“安全”道具包装所有 HOC,并在内部使用“安全”道具将 ref 传递给链中的最低组件。
2021-06-13 11:09:08
如果您将组件封装在像 React-Reduxconnect或 marterial-ui这样的 HOC 中,您会怎么做withStyles
2021-06-18 11:09:08
抱歉,我需要更多详细信息。不确定到底是什么问题。
2021-06-20 11:09:08
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()} />
)

您需要使用不同的props名称将 ref 转发到类。innerRef在许多图书馆中常用。

在你的代码beautifulInputElement中更多的是一个函数而不是一个 React 元素,它应该是这样的const beautifulInputElement = <BeautifulInputForwardingRef ref={ref => ref && ref.focus()} />
2021-05-30 11:09:08

基本上,这只是一个 HOC 函数。如果您想在课堂上使用它,您可以自己完成并使用常规props。

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

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

例如,此模式用于并在那里styled-components调用innerRef

使用不同名称的道具 likeinnerRef完全没有抓住重点。目标是完全透明:我应该能够将 a<FancyButton>视为常规 DOM 元素,但是使用样式化组件方法,我需要记住该组件对 refs 使用任意命名的 prop 而不仅仅是ref.
2021-06-12 11:09:08
在任何情况下,styled-components 都打算放弃支持innerRef,转而使用 将 ref 传递给孩子React.forwardRef,这正是 OP 试图完成的。
2021-06-19 11:09:08

如果您愿意,可以使用高阶组件来完成此操作:

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-refhttps : //www.npmjs.com/package/react-with-forwarded-ref

如果您需要在许多不同的组件中重用它,您可以将此功能导出为 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