将 forwardRef 与 withRouter 一起使用的正确方法是什么

what is the right way to use forwardRef with withRouter

我只是尝试将 forwardRef 与 withRouter(mycomponent) 一起使用,如下所示:

export default function App() {

  const childRef = useRef();
  const childWithRouteRef = useRef();

  useEffect(()=>{
    console.log("childWithRouteRef",childWithRouteRef);
    childRef.current.say();
    childWithRouteRef.current.say();
  })


  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <BrowserRouter>
      <Child ref={childRef}/>
      <ChildWithRoute_ ref={childWithRouteRef}/>
      </BrowserRouter>
    </div>
  );
}

const Child = forwardRef((props, ref) => {
  useImperativeHandle(ref, () => ({
        say: () => {
      console.log("hello")
        },
  }));

  return <div>Child</div>
})

const ChildWithRoute = forwardRef((props, ref) => {
  useImperativeHandle(ref, () => ({
        say: () => {
      console.log("hello")
        },
  }));

  return <div>ChildWithRoute</div>
})

const ChildWithRoute_ = withRouter(ChildWithRoute)

如果我将我的组件包装在 withRouter HOC 中,ref 将不起作用,它始终为 null。那么如何将 forwardRef 与包含在 withRouter 中的组件一起使用?

Forwarding refs in higher order components

... refs will not get passed through. That’s because ref is not a prop. Like key, it’s handled differently by React. If you add a ref to a HOC, the ref will refer to the outermost container component, not the wrapped component.

看起来 withRouter HOC 还没有转发 refs。您可以创建自己的小 HOC 以将 ref 转发给 decorated-with-router 组件

const withRouterForwardRef = Component => {
  const WithRouter = withRouter(({ forwardedRef, ...props }) => (
    <Component ref={forwardedRef} {...props} />
  ));

  return forwardRef((props, ref) => (
    <WithRouter {...props} forwardedRef={ref} />
  ));
};

用法:

const ChildWithRoute = forwardRef((props, ref) => {
  useImperativeHandle(ref, () => ({
    say: () => console.log("hello from child with route"),
  }));

  return <div>ChildWithRoute</div>;
})

const ChildWithRouteAndRef = withRouterForwardRef(ChildWithRoute);

...
<ChildWithRouteAndRef ref={childWithRouteRef} />

经过快速 google 搜索,我发现了这个 issue,并且根据时间戳和最后一条评论,似乎不太可能得到解决。我上面的解决方案和分享的几个方法类似。