【问题标题】:React force re-mount component on route change在路由更改时反应力重新安装组件
【发布时间】:2017-07-26 16:25:44
【问题描述】:

当对两个路由使用相同的组件时,如何在路由更改时重新安装组件?

这是我的代码。

routes.jsx

<Router history={browserHistory}>
  <Route path="/" component={Home} />
  <Route path="/foo/:fooId" component={Home} />
</Router>

我在Home 组件中对fooId 进行了条件检查,从而相应地呈现 JSX。

<Link to="/foo/1234">fooKey</Link>

此时,当点击fooKey 时,路由发生变化,Home 组件中的渲染功能被重新触发,但没有再次挂载。

我查看了提到componentWillReceiveProps 的其他答案,但我在constructor 中有很多配置,我不想将所有这些配置移动到componentWillReceiveProps

如果需要更多信息,请发表评论。

【问题讨论】:

  • 强制卸载是 React 中的反模式。 componentWillReceiveProps 是执行此操作的正确方法,然后您的代码将匹配其他读者/贡献者的期望。
  • 同意,没有好的方法可以做到这一点,即使有,你也不应该这样做。如果构造函数中有配置或数据在实例化后需要可变,则应将其移出构造函数并移入state
  • 感谢您的建议。如果您能指出有关不应重新安装组件的更多解释,那将很有帮助。很明显会降低性能但还有其他原因吗?
  • 我的意思是,它完全违背了 React 组件生命周期的预期使用方式。这有点像问“为什么我不应该用螺丝刀而不是锤子来敲这个钉子?很明显它会降低性能,但还有其他原因吗?” :P
  • 强比喻,我必须说!但是,我仍然不相信这违反了 React 组件生命周期的使用。重新安装只会从头开始重新安装过程,这当然是一种浪费,我同意这一点。

标签: reactjs react-router


【解决方案1】:

如果您需要在每个路由匹配上强制重新安装组件,您可以通过 key 属性来实现它,除非您知道自己在做什么:

<Route
  exact
  path={'some path'}
  render={props => <RemountAlways key={Date.now()} {...props} />}
/>

key={Date.now()}这个key属性每次都会强制react重新挂载。

注意: componentWillReceiveProps 在 react 中是个坏消息。

【讨论】:

    【解决方案2】:

    因此,您不会希望在每次查询字符串更改时卸载和重新安装组件。将您的路线更改为:

    <Router history={browserHistory}>
      <Route path="/" component={Home} />
    </Router>
    

    用 React Router 提供的 withRouter HoC 包裹你的 &lt;Home /&gt; 组件。完成此操作后,({ match, history, location }) 将在 &lt;Home /&gt; 组件中可用。在您的 componentWillRecieveProps 生命周期挂钩中,您可以执行任何需要 props.location.search 上的查询字符串来产生所需结果的逻辑。

    【讨论】:

      【解决方案3】:

      如果您需要强制重新安装,显然您做错了什么。一般来说,你应该对componentWillReceiveProps做出反应:

      class DumbComponent extends React.Component {
        constructor(props) {
          super(props);
      
          this.state = this.propsToState(this.props);
        }
      
        componentWillReceiveProps(nextProps) {
          this.setState(this.propsToState(nextProps));
        }
      
        propsToState(props) {
          // place all of your state initialization dependent logic here
          return {
            foo: props.foo,
          };
        }
      
        render() {
          return <div>{this.state.foo}</div>
        }
      }
      

      【讨论】:

      • 这不是处理 props 和 state 的方式。您需要任何数据的单一事实来源。如果您的渲染需要状态和道具的组合,您可以在需要时执行该逻辑。
      猜你喜欢
      • 2018-08-06
      • 2019-11-27
      • 2018-01-05
      • 1970-01-01
      • 1970-01-01
      • 2018-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多