簡體   English   中英

如何在React ES6中優雅地修改表單組件狀態內的嵌套數據?

[英]How to elegantly modify nested data within a form component's state in React ES6?

我希望能夠在React ES6的表單組件狀態下修改一些嵌套數據(對象內的對象)。 我目前有一個可行的解決方案,但我覺得可以更優雅地完成。

我要修改的狀態的形狀是:

    this.state = {
        form: {
            address: {},
        },
    };

我希望能夠在address: {}添加/編輯數據。 我目前的工作解決方案是:

    onChange(event) {
        const { form } = this.state;
        const target = event.target;
        const value = target.type === 'checkbox' ? target.checked : target.value;
        const name = target.name;

        name === 'street' || name === 'city'
            ? this.setState({
                  form: {
                      ...form,
                      address: {
                          ...form.address,
                          [name]: value,
                      },
                  },
              })
            : this.setState({
                  form: {
                      ...form,
                      [name]: value,
                  },
              });
    }

如何使該解決方案更優雅? 有條件必要嗎? 如果要在同一表單組件狀態下編輯其他嵌套對象,如何使它更具動態性?

如果我目前所處的位置正確,如何使this.setState()修改address: {}更動態? 如何使它接受嵌套對象的任何名稱,無論是“地址”還是其他名稱?


更新

幾分鍾前,我想出了一個更精簡,有效的解決方案,實際上我比上面的解決方案更喜歡。 這是重構的解決方案:

    onChange(event) {
        const { form } = this.state;
        const target = event.target;
        const value = target.type === 'checkbox' ? target.checked : target.value;
        const name = target.name;
        const object = 'address';

        name === 'street' || name === 'city'
            ? (form[object][name] = value)
            : (form[name] = value);
        this.setState({
            form,
        });
    }

因此,使用此新代碼,如何使它更具動態性? 更具體地說,如何更改const object = 'address'; 更動態地取決於正在更改的輸入?

看一看不變性幫助程序庫。 它可以將您的代碼變成:

  onChange(event) {
    const { type, checked, value, name } = event.target;

    const updatedValue = type === 'checkbox' ? checked : value;

    this.setState(state => {
      if (name === 'street' || name === 'city') {
        return {
          form: update(state.form, {
            address: {
              [name]: { $set: updatedValue },
            },
          })
        };
      }

      return {
        form: update(state.form, {
          [name]: { $set: updatedValue },
        }),
      }
    });
  }

或者,您甚至可以執行以下操作:

onChange(event) {
    const { type, checked, value, name } = event.target;

    const updatedValue = type === 'checkbox' ? checked : value;
    const updatedObject = { [name]: { $set: updatedValue } };

    this.setState(state => ({
      form: update(state.form, (name === 'street' || name === 'city') ? { address: updatedObject } : updatedObject)
    }));
  }

有兩種方法可以實現“更優雅”的功能,但不能實現同一功能。 第一件事是提取狀態更新程序功能。 在您的示例中,我將執行以下操作:

const updateForm = (key, value) => ({form}) => ({ ...form, [key]: value });

const updateAddress = (key, value) => updateForm("address", {...form.address, [key]: value});

onChange(event) {
   const { form } = this.state;
   const target = event.target;
   const value = target.type === 'checkbox' ? target.checked : target.value;
   const name = target.name;

   if (name === 'street' || name === 'city') {
     this.setState(updateAddress(name, value));
   } else {
     this.setState(updateForm(name, value));
   }
}

請注意,我正在使用setState的版本,該版本采用形式(prevState, props) => { partialState }函數,並使用解構從setState傳遞的prevState form

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM