Home > Blockchain >  How to send updated state only and not whole object
How to send updated state only and not whole object

Time:10-22

Can anyone advise on how to approach this problem?

i have a form with various state. When the user changes any of the forms inputs and clicks save, a function sends the data to the backend. The problem is that I send the whole object to the backend when I only want to send the changed value / the state that has changed. How would I do that?

Here is an example:


    const [streetName, setStreetName] = useState<string>('');
    const [zipCode, setZipCode] = useState<string>('');
    const [city, setCity] = useState<string>('');
    const [email, setEmail] = useState<string>('');
    const [phone, setPhone] = useState<string>('');

    const userData = {
        streetName,
        zipCode,
        city,
        email,
        phone
    };

    const saveDataOnClickHandler = (userData) => {
        updateUserMutation(userData);
    };

CodePudding user response:

Assuming that you start with empty string and this initial state (useState<string>('');), you can simply filter fields with empty string before sending e.g.

const userData = {
    streetName !== '' ? streetName : undefined,
    zipCode !== '' ? zipCode : undefined,
    city !== '' ? city : undefined,
    email !== '' ? email : undefined,
    phone !== '' ? phone : undefined
};

If you want to send fields that changed from last send, then you need to save these values and compare it with actual input

streetName !== previouslySentStreetName ...

CodePudding user response:

It depends, as you are not showing the form i would assume that the actual value of the inputs its linked to the state. In this case i would add a hasChanged property to each state and onSubmit i would send a fresh new userData object:

const initValue = {
  value: '',
  hasChanged: false,
};

const [streetName, setStreetName] = useState(initValue);
const [zipCode, setZipCode] = useState(initValue);
const [city, setCity] = useState(initValue);
const [email, setEmail] = useState(initValue);
const [phone, setPhone] = useState(initValue);

const userData = {
  streetName,
  zipCode,
  city,
  email,
  phone,
};

const handleOnStreetChange = (event)=>{

    setStreetName({
        value: event.target.value,
        hasChanged: true,
      });
}
const handleOnZipCodeChange = (event)=>{

    setZipCode({
        value: event.target.value,
        hasChanged: true,
      });
}


const saveDataOnClickHandler = (userData) => {


    let freshUserData = {};

    Object.entries(userData).forEach((data) => {

      [key, value] = data;

      freshUserData = value.hasChanged
        ? { ...freshUserData, [key]: value }
        : freshUserData;
    });

  sendDataToBackend(freshUserData)
};

const submitForm = (e) => {
    e.preventDefault();
    saveDataOnClickHandler(userData)
  };


return (
  <>
    <form aria-label='form'>
      <input
        type='text'
        placeholder='Street Name'
        name='streetName'
        value={streetName}
        onChange={handleOnStreetChange}
      />
      <input
        type='text'
        placeholder='Zip Code'
        name='zipCode'
        value={zipCode}
        onChange={handleOnZipCodeChange}
      />

      <button type="submit" onClick={submitForm}>
        Send
      </button>
    </form>
  </>
);
  • Related