Home > Blockchain >  React, Update form state in generic way
React, Update form state in generic way

Time:08-30

I am following the pattern for React Forms with Typescript. After each object member is changed, I write this to update the state.

We have 10 fields. Is there any generic way of updating the fields, with properly methodology in React Typescript? Below seems repetitive. Is use of any recommended?

There is a mix of textboxes, dropdowns, and checkboxes in our form.

https://onestepcode.com/creating-a-material-ui-form/

  const onProductNameChange = (e: string) => {
    setProductFilter({
      ...productFilter,
      productName: e,
    });
  };

  const onProductStatusChange = (e: string) => {
    setProductFilter({
      ...productFilter,
      productStatus: e,
    });
  };


  const onLocationsChange = (e: Array<number>) => {
    setProductFilter({
      ...productFilter,
      serviceLocations: e,
    });
  };

  const onProvidersChange = (e: Array<number>) => {
    setProductFilter({
      ...productFilter,
      providers: e,
    });
  };

.... ....

  <TextField
    value={product.feeName}
    label="Search by name"
    onChange={event => {
      onProductNameChange(event.target.value);
    }}
    }
  />
   <TextField
    value={product.productStatus}
    label="status"
    onChange={event => {
      onProductStatusChange(event.target.value);
    }}
    }
  />

CodePudding user response:

One solution is to pass the name of the property you want to update as an argument using keyof {Type}. The downside to this is that you lose the static typing on the value.

const onProductChange = (key: keyof ProductFilter, value: any) => {
  setProductFilter({
    ...productFilter,
    [key]: value,
  });
};

...

<TextField
  value={product.feeName}
  label="Search by name"
  onChange={event => {
    onProductChange('name', event.target.value);
  }}
/>

CodePudding user response:

Is there any generic way of updating the fields

Yes, there is.

If we assign a name or any other defining characteristic to each TextField,
then we could use a single function for all of them.

Example:

function handleChange(event) {
   setProductFilter({
      ...productFilter,
      [event.target.name]: event.target.value
   })
}


<TextField
   name='productName'
   value={product.feeName}
   label="Search by name"
   onChange={handleChange}
/>

<TextField
   name='productStatus'
   value={product.productStatus}
   label="Search by name"
   onChange={handleChange}
/>

What we do here is assign the newly given value to the field within the state that has the same name as it's corresponding TextField.

  • Related