在重定向

时间:2017-04-25 03:36:47

标签: reactjs

我目前在http://example.com/parentdir/module/2/

此URL实际上加载了Module.js类,如以下路由所示:

<Route exact path={"/parentdir/module/:id"} component={Module} />

这包含在我的index.js文件中定义的<BrowserRouter><Switch>元素中。

Module类有constructorcomponentWillMount方法。这些设置了记录#2的初始细节和负载信息。到目前为止一切正常。

现在,我的问题是在Module.js的孙子组件中,我使用以下重定向重定向到另一个页面,例如第3页:

return (
        <Redirect to="/parentdir/module/3/" />
)

构造函数或componentWillMount不运行,因此记录#3无法正确加载。这是因为这个组件已经从加载记录#2时加载到内存中了吗?重新加载Module.js的最佳方法是什么,以便正确加载记录#3?我是否必须重新初始化课程?或者我是否必须以某种方式将孙子组件中的数据传递回模块类?后一种方法似乎很乏味。

请注意,如果我直接转到地址栏中的http://example.com/parentdir/module/3,一切正常,但如果我在ReactJS环境中重定向到同一地址,则无法正常工作。

更新

到目前为止,我的问题有两个答案。一种解决方案建议使用componentWillReceiveProps。另一种解决方案建议将一种方法作为支撑物传递给孩子,然后传递给孙子。使用这些方法是否有利有弊,还是只是偏好?

2 个答案:

答案 0 :(得分:2)

idprop的形式传递给this.props.params.id,因此您应该使用componentWillReceiveProps生命周期方法,该方法每次props更改时都会运行就是你的情况正在发生的事情。

当您从componentWillMount导航到/parentdir/module/2时,/parentdir/module/3方法将无法运行,因为该组件已为mounted。它只会在您从其他组件导航时运行(例如,当您直接进行导航时)。

Module组件中添加此生命周期方法

componentWillReceiveProps(nextProps){
      if(nextProps.params.id != this.props.params.id){
          //load information etc (whatever you are doing in componentWillMount)
       }
}

正在发生的事情是,当它收到更新的props时,它会比较参数id是否已更改(所有路径参数都存在于params对象中props当它看到有变化时,它执行逻辑。这种比较并不是必需的,你可以在componentWillReceiveProps方法中添加逻辑,但是每次props对象发生变化时都会调用它,效率很低(可能不是id完全是param。

答案 1 :(得分:1)

componentWillMount() componentDidMount()只会执行一次!

(根据反应组件生命周期https://facebook.github.io/react/docs/react-component.html#the-component-lifecycle

如果您希望每次更新孙子模块时更新模块,您需要在模块中创建一个功能,并将其作为道具传递给子项和孙子模块(在主模块的渲染方法中)

该函数( updateThisModule )和你的render方法看起来像这样:

下面的编辑版本:(这只是关于如何从多级子组件触发父组件的回调函数的演示,我们实际上可以在该回调中做任何事情)

import React from 'react';

class Module extends React.Component {

  constructor(props) {
    super(props);
    // ...
  }

  updateThisModule = () => {
    // We can do whatever we want here, either forceUpdate the component
    // or setState, which will also trigger this component to update itself
    // (using setState is more natural, though)
    // *** OPTION 1
    // this.forceUpdate();
    // *** OPTION 2
    // this.setState({
    //   someState: 'someValue',
    //   ..
    // });
    // *** ...
    // ...
  }

  render(){
    // ...
    <ChildModule updateParent={this.updateThisModule} />
    // ...
  }
}

同样,在子模块的render方法中执行相同的操作(将该函数再向下传递给孙子模块):

class ChildModule extends React.Component {
  ...
  render(){
    // ...
    <GrandChildModule updateGrandParent={this.props.updateParent} />
    // ...
  }
}

之后,在Grand-Child-Module中,我们需要一个触发器来调用顶级Module进行更新,我建议你在componentDidUpdate()函数中触发它。然后,Grand-Child-Module可能看起来像这样:

class GrandChildModule extends React.Component {
  constructor(props) {
     super(props);
     // ...
  }

  componentDidUpdate() { 
    // this will be executed every time this grand-child-module updates itself
    // we will then trigger the update function upward to the parent's level first, then the grand-parent's level (which is your main Module)
    this.props.updateGrandParent(); 
  }

  render(){
    // ...
  }
}

上面的代码是用ES6编写的,如果你用不同的方式编写代码,可以随意在这里发布,然后我们可以一起修改代码使其工作!

PS:将函数作为道具传递给子元素也是纯React组件的主要思想。但是,如果您的模块层次结构太深(有很多子,孙子,曾孙等),您可以考虑使用Flux或Redux