【问题标题】:Why state dependant on props in child component isn't updated when passed props are changing?为什么当传递的道具发生变化时,依赖于子组件中道具的状态不会更新?
【发布时间】:2020-05-16 22:35:16
【问题描述】:

我正在尝试创建一个动态表单组件,并且我的 Auth 组件的状态如下所示:

  state = {
    signUpMode: true,
    formComponents: {
      email: {
        elements: {
          elementType: "input",
          label: "E-mail",
        },
        configs: {
          type: "email",
          placeholder: "E-mail",
          value: "",
          name: "email",
        },
        validation: {
          required: true,
        },
        isValid: false,
        error: "",
      },
      password: {
        elements: {
          elementType: "input",
          label: "Password",
        },
        configs: {
          type: "password",
          placeholder: "Password",
          value: "",
          name: "password",
        },
        validation: {
          required: true,
        },
        isValid: false,
        error: "",
      },
      submit: {
        elements: {
          elementType: "input",
        },
        configs: {
          type: "submit",
          value: "Sign Up",
          name: "signup",
        },
      },
    },
  };

formComponents 保存了每个输入的所有配置,我将它们作为道具传递给我的表单组件

 render() {
    return (
      <div className="auth">
        <Form submitHandler={this.props.Auth} signUp={this.state.signUpMode} formInputs={this.state.formComponents}></Form>
        <button className="switch-auth-mode" onClick={this.switchAuthMode}>
          Switch to {this.state.signUpMode ? "Sign In" : "Sign Up"}
        </button>
      </div>
    );
  }

一切正常,除了你可以看到我有这个按钮可以更改为注册模式或登录模式,它将 formComponents 中提交元素的值更改为注册或登录

<button className="switch-auth-mode" onClick={this.switchAuthMode}>

switchAuthMode 改变了 signUpMode 并且回调应该改变提交的文本,它确实

switchAuthMode = () => {
    this.setState((prevstate) => {
      return {
        signUpMode: !prevstate.signUpMode,
      };
    }, this.switchButton);
  };

我正在使用 lodash clonedeep 来克隆 formComponents

switchButton = () => {
    let formComponents = cloneDeep(this.state.formComponents);

    if (this.state.signUpMode) {
      formComponents.submit.configs.value = "Sign Up";
    } else {
      formComponents.submit.configs.value = "Sign In";
    }
    this.setState({ formComponents });
  };

问题现在出在我的表单组件上,当我更改提交元素中的注册或登录值时,它不会改变它保持初始值,它正确接收它作为道具但内部状态没有改变,换句话说,状态没有更新为什么?

我尝试在componentDidMount() 中设置状态,如下所示:

state = {
    formInputs: {},
  };
  componentDidMount() {
    this.setState({ formInputs: this.props.formInputs }, () => {
      console.log(this.state);
    });
  }

或者直接这样:

state = {
    formInputs: {...this.props.formInputs},
  };

但是没有一个工作,我做错了什么?

正如 Zimri Leijen 建议的那样,我添加了

componentDidUpdate(prevProps) { if (this.props.signUp !== prevProps.signUp) { this.setState({ formInputs: this.props.formInputs }); } }

现在的问题是第一次点击没有更新,但在第二次是,它显示错误,什么时候应该注册显示登录,相反

【问题讨论】:

  • 如果您在switchButton 方法中注销this.state.signUpMode,它是否显示更新状态?我想知道this.state 是否仍然指的是旧状态。
  • @RobertCooper 是的,它显示正确,因为我在 setState() 之后将它用作回调

标签: reactjs


【解决方案1】:

组件不会在每次 prop 更改时重新挂载。因此componentDidMount() 不会触发,您的状态也不会更新。

您需要不同的生命周期方法

在这种情况下,componentDidUpdate() 非常合适。

【讨论】:

  • componentDidUpdate(prevProps) { if (this.props.signUp !== prevProps.signUp) { this.setState({ formInputs: this.props.formInputs }); } } 问题现在是第一次点击没有更新,但在第二次是的,它显示错误,什么时候应该注册显示登录,相反
猜你喜欢
  • 2018-01-13
  • 1970-01-01
  • 2020-09-24
  • 2020-10-23
  • 1970-01-01
  • 2020-11-10
  • 1970-01-01
  • 2019-12-14
  • 1970-01-01
相关资源
最近更新 更多