Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Forward ref through React Router's withRouter HOC

I'd like to manage to focus on a component that I've wrapped with withRouter. However, when I give the component a ref, I get the a warning about assigning a ref to a stateless component. I'm assuming this is because the ref is being attached to the withRouter HOC and not my component, as it is stateful. My general set up looks like this:

// InnerComponent.js

class InnerComponent extends Component {
   constructor(props) {
      super(props);
   }
}

export default withRouter(InnerComponent);

// App.js

class App extends Component {
   constructor(props) {
      super(props);
      this.myRef = React.createRef();
   }

render() {
    return (
       <Router>
           <InnerComponent ref={this.myRef}>
       </Router>
    );
}

I see this question has been asked before, but never answered. I'm new to React so please forgive me if I'm missing something obvious. Thanks in advance.

EDIT: I'm fairly sure what I need is here: https://reacttraining.com/react-router/web/api/withRouter, in the wrappedComponentRef section of the withRouter docs, but I don't understand how to implement it.

like image 639
user3150583 Avatar asked Aug 30 '18 12:08

user3150583


Video Answer


1 Answers

Based on @Ranjith Kumar answer I came up with the following solution that:

  • Is a bit shorter/simpler (no need for class component or withRef option)
  • Plays a bit better in tests and dev tools
const withRouterAndRef = Wrapped => {
  const WithRouter = withRouter(({ forwardRef, ...otherProps }) => (
    <Wrapped ref={forwardRef} {...otherProps} />
  ))
  const WithRouterAndRef = React.forwardRef((props, ref) => (
    <WithRouter {...props} forwardRef={ref} />
  ))
  const name = Wrapped.displayName || Wrapped.name
  WithRouterAndRef.displayName = `withRouterAndRef(${name})`
  return WithRouterAndRef
}

Usage is the same:

// Before
export default withRouter(MyComponent)
// After
export default withRouterAndRef(MyComponent)
like image 96
Pandaiolo Avatar answered Oct 05 '22 23:10

Pandaiolo