多次单击同一反应路由器链接时强制重新安装组件

时间:2019-09-04 10:57:52

标签: reactjs react-router react-router-v4 react-router-dom

我有一个带有数据表的路由页面,在安装组件时会提取数据。当我多次单击相同的react-router-dom链接(指向上面的路由)时,似乎只有在更改路线时才卸载组件(具有要渲染的不同组件)。

我希望再次单击同一链接时必须重新安装组件,以获取新数据。在react-router-dom Link或任何其他Link组件中是否有任何选项,或执行此操作的任何技巧?

我的示例代码在这里:https://codesandbox.io/s/react-router-9wrkz

我希望当多次单击“关于”链接时,将重新安装“关于”组件

4 个答案:

答案 0 :(得分:2)

一种强制重新安装组件的方法是更改​​key属性:

  <Route
    path="/about"
    render={props => <About key={Date.now()} {...props} />}
  />

https://codesandbox.io/s/react-router-6cptd

答案 1 :(得分:2)

您可以使用此方法进行渲染

componentWillReceiveProps(recievedProps) {
    console.log("componentWillReceiveProps called");
    if (
      recievedProps &&
      this.props &&
      recievedProps.location &&
      this.props.location &&
      recievedProps.location.key &&
      this.props.location.key &&
      recievedProps.location.key !== this.props.location.key
    ) {
      this.setState({ loading: true });
      promise().then(result => {
        this.setState({ value: result, loading: false });
      });
    }
  }

答案 2 :(得分:0)

为什么不通过在组件中创建函数来强制重新加载onClick:

remount(){
    location.reload(true);
}

然后将onClick处理程序分配给链接:

<Link to="/your route" onClick = {this.remount}>

除非您对重新加载页面有异议,否则似乎工作正常。

答案 3 :(得分:0)

供将来参考。除了上面提到的答案之外,我还需要调整一些东西,因为它们都不是我想要的。之前提到了道具的比较,但是因为键在一个对象(引用)中,所以它从未看到更新(您正在比较同一个对象)。所以我通过将其保存为道具来跟踪。

我更喜欢使用 componentDidUpdate 更好,因为当您可能只需要更新某些元素时,您不会卸载和安装整个组件,

对于这个例子,你的组件确实需要使用 withRouter() 来链接,这样你就可以访问路由道具。

    // You cant use prevProps because object will be the same, so save it in component
    private currentRouteLocationKey: string| undefined; 

    public componentDidUpdate(): void {
    const currentRouteKey = this.props.history.location.key;

        // Compare keys so you only update when needed
        if (this.currentRouteLocationKey !== currentRouteKey) {
            // Add logic you want reset/ updated
            this.refreshPage();

            // Save the new key
            this.currentRouteLocationKey = currentRouteKey;
        }
    }