通过React Router的withRouter HOC转发参考

时间:2018-08-30 12:51:48

标签: javascript reactjs react-router

我想集中精力于withRouter包装的组件。但是,当我给组件提供引用时,会收到有关将引用分配给无状态组件的警告。我假设这是因为ref被附加到withRouter HOC而不是我的组件上,因为它是有状态的。我的常规设置如下:

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

我看到这个问题曾被问过,但从未得到回答。我是React的新手,如果我遗漏了一些明显的东西,请原谅我。预先感谢。

编辑:我相当确定我需要的是:https://reacttraining.com/react-router/web/api/withRouter,在withRouter文档的wrappedComponentRef部分中,但我不知道如何实现。

7 个答案:

答案 0 :(得分:3)

最后,我已经这样做了!这肯定可以工作

SELECT *

答案 1 :(得分:3)

基于@Ranjith Kumar的答案,我提出了以下解决方案:

  • 有点短/简单(不需要类组件或withRef选项)
  • 在测试和开发工具中发挥更好的作用
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
}

用法相同:

// Before
export default withRouter(MyComponent)
// After
export default withRouterAndRef(MyComponent)

答案 2 :(得分:0)

我认为您可以像这样使用React.forwardRefhttps://reactjs.org/docs/forwarding-refs.html):

// InnerComponent.js

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

export default withRouter(InnerComponent);

// App.js

const InnerComponentWithRef = React.forwardRef((props, ref) => <InnerComponent ref={ref} props={props} />);

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

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

注意:未经测试的代码!

答案 3 :(得分:0)

我想您可以在导出组件时使用withRef选项。

请参阅以下示例进行导出

    // InnerComponent.js

    class InnerComponent extends Component {
       constructor(props) {
          super(props);
          this.exampleMethod = this.exampleMethod.bind(this);
       }

       exampleMethod(){

       }
    }

export default withRouter(InnerComponent , { withRef: true });

并尝试以下方法以使用引用访问这些方法

this.myRef.getWrappedInstance().exampleMethod()

答案 4 :(得分:0)

HOC组件使用withRouter HOC转发内部组件引用

const withRouterInnerRef = (WrappedComponent) => {

    class InnerComponentWithRef extends React.Component {    
        render() {
            const { forwardRef, ...rest } = this.props;
            return <WrappedComponent {...rest} ref={forwardRef} />;
        }
    }

    const innerComponentWithRef = withRouter(InnerComponentWithRef, { withRef: true });

    return React.forwardRef((props, ref) => {
        return <innerComponentWithRef {...props} forwardRef={ref} />;
      });
}

用法

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

export default withRouterInnerRef(InnerComponent);

答案 5 :(得分:0)

一种更简单的方法:

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

    export default withRouter(InnerComponent);

    // App.js

    import InnerComponentWithRouter, { InnerComponent } from '/InnerComponent'

    class App extends Component {
        private myRef: InnerComponent|null = null;
        constructor(props) {
            super(props);
        }

        render() {
            return (
                <Router>
                    <InnerComponentWithRouter wrappedComponentRef={(r: InnerComponent) => this.myRef = r} />
                </Router>
            );
        }
    }

答案 6 :(得分:0)

good answer简化了@pandaiolo。使用wrappedComponentRef

已使用的withRouter
function withRouterAndRef(WrappedComponent) {
    const RoutableComponent = withRouter(WrappedComponent);
    const RoutableComponentWithRef = React.forwardRef((props, ref) => (
        <RoutableComponent {...props} wrappedComponentRef={ref} />
    ));
    const name = WrappedComponent.displayName || WrappedComponent.name;
    RoutableComponentWithRef.displayName = `withRouterAndRef(${name})`;
    return RoutableComponentWithRef;
}