【问题标题】:Force remount component when click on the same react router Link multiple times多次单击同一个反应路由器链接时强制重新安装组件
【发布时间】:2019-09-04 10:57:52
【问题描述】:

当组件挂载时,我有一个带有数据表获取数据的路由页面。当我多次单击同一个 react-router-dom 链接(到上面的路由)时,似乎组件仅在路由更改时才卸载(要渲染不同的组件)。

我希望在再次单击同一链接时强制重新安装组件以获取新数据。 react-router-dom Link 或任何其他 Link 组件中是否有任何选项或任何技巧可以做到这一点?

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

我希望在多次单击关于链接时重新安装关于组件

【问题讨论】:

  • 我已经用你的代码框更新了我的答案
  • 很好,谢谢@Mohamed Ramrami,这是实现这一目标的最佳做法
  • 我不知道这是否是“最好的”,但可能是强制重新安装的最简单方法。

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


【解决方案1】:

强制重新挂载组件的一种方法是更改​​key 属性(您可以使用Date.now()props.location.key):

  <Route
    path="/about"
    render={props => <About key={props.location.key} {...props} />}
  />

【讨论】:

  • 回到这个问题,我使用 props.location.key 作为组件键。但是如果我想在不更改强制重新安装的密钥的情况下推送 URL。这意味着有时我想强制重新安装,有时不。我怎样才能做到这一点
【解决方案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 });
      });
    }
  }

【讨论】:

    【解决方案3】:

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

    我更喜欢使用 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;
            }
        }
    

    【讨论】:

      【解决方案4】:

      这意味着有时我想强制重新安装,有时不。我怎样才能做到这一点

      这种方法怎么样? 它仅在 PUSH 上重新安装。 不会在 REPLACE 上重新挂载。

      https://codesandbox.io/s/react-router-forked-z8uco?file=/index.js

      export function withRemountOnHistoryPush(Component) {
        const DecoratedComponent = (props) => {
          const [key, setKey] = React.useState(0);
          const history = useHistory();
          React.useEffect(() => {
            return history.listen((_, action) => {
              if (action !== "PUSH") return;
              setKey((prev) => prev + 1);
            });
          }, [history]);
          return <Component key={key} {...props} />;
        };
        return DecoratedComponent;
      }
      

      【讨论】:

        【解决方案5】:

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

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

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

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

        除非您反对重新加载页面,否则似乎可以正常工作。

        【讨论】:

        • location.reload 似乎刷新了整个页面,但我只想重新安装组件
        • 它只是用相同的旧内容重新加载页面
        猜你喜欢
        • 2020-02-05
        • 2016-01-31
        • 2018-06-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多