繁体   English   中英

子状态无状态功能组件即使在父状态更新后也不会更新

[英]Child Stateless Functional Component doesn't update even after parent State updates

我的父组件的状态为formIsValid ,最初设置为false。 我的表单也有一个提交按钮。 我希望禁用提交按钮,直到某些输入字段(输入的名字和姓氏)中包含数据之后。

这是我的状态:

  state = {
    employees: [],
    costEstimates: emptyCosts(),
    relationshipOptions: [],
    newEmployee: emptyEmployee(),
    formIsValid: false
  };

此函数处理对名字和姓氏输入的更改:

  // handle input into "First Name" and "Last Name" inputs
  handleChangeValue = async e => {
    const newEmployee = { ...this.state.newEmployee };
    newEmployee[e.currentTarget.name] = e.currentTarget.value;

    this.setState({ newEmployee });

    this.validateIfCanBeSubmitted();

    await this.updateCostsData(newEmployee); // this is an api thing, not relevent
  };

这就是将formIsValid属性设置为状态的原因。 此属性作为道具发送到“提交”按钮。

  validateIfCanBeSubmitted = () => {
    const { firstName, lastName } = this.state.newEmployee;

    let formIsValid = firstName && lastName ? true : false;

    this.setState({ formIsValid });
  };

如果状态中的employee属性的名字和姓氏为空,则此“提交”按钮将被正确禁用。 问题在于它“在1次更新后关闭”。 好像道具直到下一次状态改变后才传播到子按钮组件。 这是问题的gif:

在此处输入图片说明

这是子组件的外观。 它只是一个常规的HTML按钮,但是在无状态功能组件中,因此问题不在于组件的状态:

    <button
      type="button"
      onClick={onSubmit}
      className={'btn btn-primary mr-1 ' + (formIsValid ? '' : 'disabled')}
      disabled={!formIsValid}
    >

setState()是异步的!
this.validateIfCanBeSubmitted(); 在旧状态下执行; 此更新this.setState({ newEmployee }); 执行函数时尚未传播到this.state

使validateIfCanBeSubmitted更新功能。

validateIfCanBeSubmitted = ({ newEmployee: { firstName, lastName }}) => {
  return {
    formIsValid: firstName && lastName ? true : false
  };
}

并相应地使用它:

handleChangeValue = async e => {
  const {name, value} = e.currentTarget;
  const newEmployee = { 
    ...this.state.newEmployee, 
    [name]: value
  };

  this.setState({ newEmployee });
  this.setState(this.validateIfCanBeSubmitted);

  // this is an api thing, not relevant
  await this.updateCostsData(newEmployee); 
};

实际上, handleChangeValue的代码也应该在这样的函数中,因为它使用先前的状态来计算新的状态。

那么如何组合它们:

handleChangeValue = e => {
  const {name, value} = e.currentTarget;
  this.setState((state) => {
    const newEmployee = { 
      ...this.state.newEmployee, 
      [name]: value
    };
    const { firstName, lastName } = newEmployee;
    const formIsValid = firstName && lastName ? true : false;

    //and since you never use the returned Promise, why make anything async?
    this.updateCostsData(newEmployee);

    return { newEmployee, formIsValid  };
  });
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM