0

I'm coming from this thread: How to use React.forwardRef in a class based component? I also went through the docs quite carefully, but my ref forwarding simply doesn't seem to work.

Component to create ref:

class TextEditor extends Component {
    constructor(props: Props) {
        this.editor = createRef();
    }

    render() {
        console.log(this.editor) // -> This is always empty
        return (
            <BaseEditor ref={this.editor}/>
        );
    }
}

Component to receive the ref:

class BaseEditor extends Component<Props> {

    render() {
        return (
            <Editor ref={this.props.innerRef}/>
        );
    }
}

const BaseEditorForwardRef = React.forwardRef((props: any, ref: any) => (
    <BaseEditor {...props} innerRef={ref} />
));

export default connect(mapStateToProps, mapDispatchToProps)(BaseEditorForwardRef)

I feel like everything is where it should. Yet the ref does not exist within TextEditor if I'm forwarding the ref without using React.forwardRef everything works.

Does somebody know what I'm doing wrong?

Xen_mar
  • 8,330
  • 11
  • 51
  • 74

2 Answers2

2

You need to pass the ref to the already redux-connected component(i didn't try it with redux, but with another HOC, i hope it works for you):

class BaseEditor extends Component<Props> {

    render() {
        return (
            <Editor ref={this.props.innerRef}/>
        );
    }
}

const Connected = connect(mapStateToProps, mapDispatchToProps)(BaseEditor)


const BaseEditorForwardRef = React.forwardRef((props: any, ref: any) => (
    <Connected {...props} innerRef={ref} />
));

export default BaseEditorForwardRef
i.brod
  • 3,993
  • 11
  • 38
  • 74
  • fantastic, this works. I'm not exactly sure why though. The other HOC should just pass down every other prop as `{ ...props }`including the ref. Hm ... – Xen_mar Mar 11 '20 at 18:53
  • I'm not sure why either, but remember that refs aren't props. I'm glad it works. – i.brod Mar 11 '20 at 18:55
  • :-) yes, refs aren't props - true. But when forwarding them, you pin them to a prop (in my case innerRef). InnerRef in turn should be passed down from within `connect` to its children as part of the `{ ... props}` ... but yeah, it works - so no questions asked. – Xen_mar Mar 11 '20 at 18:58
  • 1
    `connect` would create an entirely new Component with its own `ref`. However, React Redux actually provides a `forwardRef` option for `connect`. I think this would work too. https://react-redux.js.org/api/connect#forwardref-boolean – kmui2 Mar 11 '20 at 19:33
0

connect would create an entirely new Component with its own ref. However, React Redux actually provides a forwardRef option for connect which should work allow for forwarding the ref.

If {forwardRef : true} has been passed to connect, adding a ref to the connected wrapper component will actually return the instance of the wrapped component.

https://react-redux.js.org/api/connect#forwardref-boolean

kmui2
  • 2,227
  • 18
  • 19