【问题标题】:Why is componentDidMount not being called when I re-render?为什么我重新渲染时没有调用 componentDidMount?
【发布时间】:2017-02-21 04:54:45
【问题描述】:

我有多种注册模式,但遇到了麻烦。我一共有三个动作。首先是注册按钮,然后激活第一个注册模式以使用 google 或 facebook 注册,然后在完成模式后,提供者无法收集的其他信息将显示为提供者收集的预填充输入。我在渲染应用程序时渲染了这两个模态,并且仅在单击注册按钮时才显示它。我需要在完成 facebook 或 google 登录后调用 componentDidMount,但是当我在应用程序启动时渲染模式时调用它。按钮点击动作减速器和减速器改变类型 bool 的状态是否显示模态。

class HeaderRegisterButton extends Component {
   render() {
     return(
       <div>
         <Register1/>
         <Register2/>
       </div>
     );
   }
 }

注册模态1

class Register1 extends Component {
   render() {
     return(
       <div>
        <button onClick={() => this.props.showRegister2()} /> //This would hit the action reducer to get initial info and change the bool to show register 1 to false and register 2 to true.
       </div>
     );
   }
 }

注册模态2

import { reduxForm, Field, initialize } from 'redux-form';

class Register2 extends Component {

  componentDidMount() {
    hInitalize() //only called when the app fires, not when the state changes in the action reducer to change bool to show this modal.
  }

  hInitalize() {
   var initData = {};
  const initData = {
   "name" = this.props.name//name stored inside redux store
  };
  this.props.initialize(initData)
  }



   render() {
     return(
       <div> 
        //Code to display the modal which works.
       </div>
     );
   }
 }

【问题讨论】:

  • componentDidMount 只被调用一次,而不是在每次重新渲染时。那将是componentDidUpdate
  • @AndrewLi 这实际上造成了一个问题,我无法输入任何输入/表单

标签: reactjs


【解决方案1】:

componentDidMount在任何组件的生命周期中只被调用一次,重新渲染不会重新初始化组件。 componentDidUpdate 将被调用,您可以在其中管理您的逻辑。

【讨论】:

【解决方案2】:

componentDidMount 只会执行一次,当 React 组件挂载时,它不会在 state 或 props 改变时执行。

因此你需要使用 componentDidUpdate 并且不要忘记比较 props 或 state (你也可以在 parent 组件中 props 更改时使用它)

  componentDidUpdate(prevProps,prevState) {
      if (this.state.userID !== prevState.userID) {
      console.log('userId changed');
   }
 }

重要:不要在没有将其包装在条件中的情况下更新 componentDidUpdate 中的状态,因为这会触发重新渲染,并且会导致无限循环

【讨论】:

    【解决方案3】:

    IMO,您不需要调用 componentDidMount,只需向父组件提供一些回调,该组件保存在此过程中所需/收集的所有信息的一些临时状态。您的每个模态框都将显示此父组件提供给它们的信息。

    这个过程是这样的。

    1. 点击注册按钮
    2. Google 和 Facebook 之间的显示选择
    3. 用户点击 Google 或 Facebook
    4. 通过社交媒体帐户执行身份验证
    5. 来自身份验证的数据发送回父组件以临时存储
    6. 显示二级注册表单,其中包含从父组件提供的数据
    7. 用户填写辅助表单
    8. 点击提交按钮
    9. 使用父组件中临时状态的数据进行操作

    希望这是有道理的:)

    更新:

    嗯,我不知道你的实现是如何......但你可以将函数传递给子组件(通过道具)并在子组件中使用它们与父组件进行通信,因此在 Facebook 身份验证的组件中具有父传递someCallback 接受下面显示的参数并将它们添加到父状态(请记住,状态的更改将导致任何使用该状态的组件更新)。我通过传递 fbLoginCallback 作为我的 Facebook 登录过程的回调来完成此操作,该过程调用 Facebook 的 FB.getLoginStatus(....)

    export class FbLoginButton extends Component {
        constructor(props) {
            super(props);
        }
        fbLoginCallback = response => {
            const { authResponse, status } = response;
            if (status === 'connected') {
                // Logged into your app and Facebook.
                const userId = authResponse.userID;
                const accessToken = authResponse.accessToken;
    
                FB.api('/me', user => {
                    const displayName = user.name;
    
                    this.props.someCallback(userId, accessToken, displayName);
                });
            }
        }
    }
    

    我已经删除了实际按钮的渲染和其他一些小东西,但这或多或少应该是回调的方式。

    【讨论】:

      【解决方案4】:

      componentDidMount 是一个生命周期方法,仅在组件挂载时调用。在第一次渲染后只调用一次。

      【讨论】:

        猜你喜欢
        • 2014-08-20
        • 2020-03-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-17
        • 2023-03-29
        • 2019-06-18
        • 2021-07-11
        相关资源
        最近更新 更多