重定向时重新初始化类

IT技术 reactjs
2021-03-28 05:34:07

我目前在 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 的最佳方法是什么?我是否必须以某种方式重新初始化课程?或者我是否必须以某种方式将数据从孙组件传递回module类?后一种方法似乎很乏味。

澄清一下,如果我直接访问地址栏中的http://example.com/parentdir/module/3一切正常,但如果我重定向到 ReactJS 环境中的同一个地址,它就无法正常工作。

更新

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

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参数)。

您的示例与 Thinhvo0108 的示例相比如何。两者似乎都是有效的方法。另外,我觉得你的最后一句话有点不清楚。
2021-05-27 05:34:07
在最后一句话中,我的意思是您可以跳过if (nextProps.params.id != this.props.params.id)条件,但这意味着任何道具在componentWillReceiveProps触发时发生变化时都会调用这些方法这可能意味着即使您没有导航到其他页面并且props正在更改其他页面,这些方法仍在运行
2021-06-03 05:34:07
这就是我建议使用 Flux 或 Redux 的原因,这将消除通过多个级别的子组件传递 props 的复杂性。但是,理论上,componentWillReceiveProps 会在 props 传入组件时执行,但传入新的 props 后,组件不会自行更新,除非我们使用 forceUpdate 或 setState。我认为这里也会建议 setState。实际上,我上面的方法只是解释了如何将父级的回调传递给其子级,当然我们也可以在该回调函数中使用 setState 。谢谢
2021-06-14 05:34:07
我的方法更符合标准,因为流程很简单,而且是一种方法。你导航到一个页面,道具改变,函数被调用。这比将函数传递给子孙后代并在子孙后代发生变化时调用该函数要直接得多。此外,它似乎真的无效,因为只要您运行updateGrandParent祖父母/父母上updateParentrender功能将被触发,这意味着将再次呈现具有相同信息的孩子(因为它们是主要组件的后代)。
2021-06-18 05:34:07

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

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

如果您希望每次孙module更新时都更新您的module,您需要在您的module中创建一个函数,并将其作为props传递给子module和孙module(在主module的渲染方法中)

该函数(updateThisModule)和您的渲染方法将如下所示:

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

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} />
    // ...
  }
}

同样,在子module的 render 方法中做同样的事情(将该函数向下传递 1 级到孙module):

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:将函数作为props传递给子组件也是纯 React 组件的主要思想。但是,如果您的module层次结构太深(有很多子、孙、曾孙等),您可以考虑使用 Flux 或 Redux

使用 setState 会很有效,因为 React 的本质是在组件状态改变时重新渲染组件。@mrinalmech 使用 setState 比使用 forceUpdate 更好。但是,我只是举例说明了如何在 Parent 上触发一个函数,我们可以在该触发函数中做任何我们想做的事情。谢谢
2021-05-23 05:34:07
那么,如果我删除 forceUpdate 行,并在它的位置发出一个 setState 它会最有效吗?此示例与使用 componentWillReceiveProps 的 minalmech 示例相比如何。两者似乎都是有效的方法。
2021-06-08 05:34:07
forceUpdate() 真的不应该使用。理想情况下,所有渲染都应该随着状态或道具的变化而发生。
2021-06-12 05:34:07