我目前在http://example.com/parentdir/module/2/
此URL实际上加载了Module.js类,如以下路由所示:
<Route exact path={"/parentdir/module/:id"} component={Module} />
这包含在我的index.js文件中定义的<BrowserRouter>
和<Switch>
元素中。
Module类有constructor
和componentWillMount
方法。这些设置了记录#2的初始细节和负载信息。到目前为止一切正常。
现在,我的问题是在Module.js的孙子组件中,我使用以下重定向重定向到另一个页面,例如第3页:
return (
<Redirect to="/parentdir/module/3/" />
)
构造函数或componentWillMount不运行,因此记录#3无法正确加载。这是因为这个组件已经从加载记录#2时加载到内存中了吗?重新加载Module.js的最佳方法是什么,以便正确加载记录#3?我是否必须重新初始化课程?或者我是否必须以某种方式将孙子组件中的数据传递回模块类?后一种方法似乎很乏味。
请注意,如果我直接转到地址栏中的http://example.com/parentdir/module/3,一切正常,但如果我在ReactJS环境中重定向到同一地址,则无法正常工作。
更新
到目前为止,我的问题有两个答案。一种解决方案建议使用componentWillReceiveProps。另一种解决方案建议将一种方法作为支撑物传递给孩子,然后传递给孙子。使用这些方法是否有利有弊,还是只是偏好?
答案 0 :(得分:2)
id
以prop
的形式传递给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