什么是在Router中使用forwardRef的正确方法

时间:2020-05-12 03:51:34

标签: reactjs react-router react-forwardref react-hoc

我只是试图将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中,则引用将不起作用,它始终为null。那么如何将forwardRef与withRouter包装的组件一起使用?

1 个答案:

答案 0 :(得分:2)

Forwarding refs in higher order components

...裁判不会通过 通过。这是因为ref不是道具。像key一样, 与React不同。如果将引用添加到HOC,则引用将引用 最外面的容器组件,而不是包装的组件。

看起来withRouter HOC尚未转发引用。您可以创建自己的小HOC,也可以将引用转发到带有路由器装饰的组件

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

Edit forwardRef - HOC

在Google快速搜索后,我发现了这个issue,并且根据时间戳和最新评论似乎不太可能解决。我上面的解决方案类似于共享的几种方法。