簡體   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