How to use React.forwardRef in a class based component?

前端 未结 5 1708
灰色年华
灰色年华 2020-12-04 10:37

I\'m trying to use React.forwardRef, but tripping over how to get it to work in a class based component (not HOC).

The docs examples use elements and functional comp

相关标签:
5条回答
  • 2020-12-04 11:06

    The idea to always use the same prop for the ref can be achieved by proxying class export with a helper.

    class ElemComponent extends Component {
      render() {
        return (
          <div ref={this.props.innerRef}>
            Div has ref
          </div>
        )
      }
    }
    
    export default React.forwardRef((props, ref) => <ElemComponent 
      innerRef={ref} {...props}
    />);
    

    So basically, yea, we are forced to have a different prop to forward ref, but it can be done under the hub. It's important that the public use it as a normal ref.

    0 讨论(0)
  • 2020-12-04 11:11

    This can be accomplished with a higher-order component, if you like:

    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
    

    And then in your component file:

    class Boop extends React.Component {
      render() {
        const { forwardedRef } = this.props
    
        return (
          <div ref={forwardedRef} />
        )
      }
    }
    
    export default withForwardedRef(Boop)
    

    I did the work upfront with tests & published a package for this, react-with-forwarded-ref: https://www.npmjs.com/package/react-with-forwarded-ref

    0 讨论(0)
  • 2020-12-04 11:12
    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()} />
    )
    

    You need to use a different prop name to forward the ref to a class. innerRef is commonly used in many libraries.

    0 讨论(0)
  • 2020-12-04 11:15

    Incase you need to reuse this in many difference components, you can export this ability to something like withForwardingRef

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

    usage:

    const Comp = ({forwardedRef}) => (
     <input ref={forwardedRef} />
    )
    const EnhanceComponent = withForwardingRef<Props>(Comp);  // Now Comp has a prop called forwardedRef
    
    0 讨论(0)
  • 2020-12-04 11:20

    Basically, this is just a HOC function. If you wanted to use it with class, you can do this by yourself and use regular props.

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

    This pattern is used for example in styled-components and it's called innerRef there.

    0 讨论(0)
提交回复
热议问题