Skip to content

Sending only the updated/newly created records to API in react hooks

I’m trying to get the updated/newly created records and send it to the backend in “queryparam”

import React, { useState, useEffect } from "react";
//import { Container, Row, Col } from "reactstrap";
// import Box from "@mui/material/Box";
// import "bootstrap/dist/css/bootstrap.css";
// import "./index.css";

const Index = () => {
  const [formValues, setFormValues] = useState([
    { orderno: 0, inputValue1: "", inputValue2: "", checked: false }
  ]);

  const [isDisabled, setDisabled] = useState(false);
  // const [inputVal1, setInputval1] = useState();
  const [isChanged, setIsChanged] = useState([]);
  const [error, setError] = useState(false);

  const [orderNumber, setOrderNumber] = useState(1);

  const addFormFields = () => {
    // if (error) {
    //   setDisabled(false)
    // }
    // else {
    //   setDisabled(true)
    // }

    setFormValues((prevState) => [
      ...prevState,
      {
        orderno: orderNumber,
        inputValue1: "",
        inputValue2: "",
        checked: false
      }
    ]);
    setOrderNumber((prev) => prev + 1);
  };

  const removeFormFields = (i) => {
    let newFormValues = [...formValues];
    newFormValues.splice(i, 1);

    setFormValues(newFormValues);
    setOrderNumber((prev) => prev - 1);
  };

  const onChangeFieldValue = (index, key, value) => {
    setFormValues((prevState) => {
      let copyState = [...prevState];
      if (value?.length > 0) {
        setError(false);
      } else {
        setError(true);
      }

      copyState[index][key] = value;

      return copyState;
    });
  };

  const saveFields = (e) => {
    const queryparam = {
      inputData: formValues
    };
    setIsChanged(queryparam);
    setIsChanged((prevState, nextState) => {
      let copyState = [];
      if (prevState === nextState) {
        copyState = [...prevState];
      } else {
        copyState = [...nextState];
      }
      return copyState;
    });
    console.log(isChanged, "lllllllll");
  };

  // useEffect(() => {
  //    saveFields()
  // }, [isChanged])

  return (
    <>
      {formValues.map((element, index) => (
        <div className="form-inline" key={index}>
          {/* <Container>
            <Row>
              <Col xs="12" sm="6"> */}
          <label>{index + 1}</label>

          <input
            type="text"
            value={element.inputVal1}
            onChange={(e) =>
              onChangeFieldValue(index, "inputValue1", e.target.value)
            }
          />
          <input
            type="text"
            value={element.inputVal2}
            required
            onChange={(e) =>
              onChangeFieldValue(index, "inputValue2", e.target.value)
            }
          />
          {/* </Col>

              <Col xs="12" sm="6">
                <Box> */}
          <button
            className={`button ${error ? "add" : "btn-secondary"}`}
            type="button"
            disabled={error}
            onClick={(e) => addFormFields(e)}
          >
            Add{console.log(isDisabled, "ooooooo", error)}
          </button>

          <button
            type="button"
            className="button remove"
            onClick={() => removeFormFields(index)}
          >
            Remove
          </button>
          {/* </Box>
              </Col>
            </Row>
          </Container> */}
        </div>
      ))}
      {/* <Row>
        <Col sm="6" md={{ size: 4, offset: 2 }}>
          <Box> */}
      <button
        type="button"
        className="button save"
        onClick={(e) => saveFields(e)}
      >
        Save
      </button>
      <button
        type="button"
        className="button remove"
        //onClick={(e) => cancelFields(e)}
      >
        cancel
      </button>
      {/* </Box>
        </Col>
      </Row> */}
    </>
  );
};

export default Index;

https://codesandbox.io/s/black-fire-ixeir?file=/src/App.js:3662-3701

In the above link,

Step1 : when I add values for inputs “123” in input1 and “345” in input2.Then when I click on “Save” the values sent are {“input1″:”123″,”input2″:”345”}. Step2: Again I try to add one row for inputs “456” in input1 and “678” in input2.Then when I click on save the values sent are {“input1″:”456″,”input2″:”678”}.

When I edit the existing row, for example the first row values and when I click on “Save” then only the first row value should be sent as the second row values hasn’t changed.Also, If I add new rows then the newly added only should be sent if the existing row values aren’t changed. Is there any way to send only the updated/newly created values to the backend using react hook

Answer

You could use a separate changes object to track changes by orderno property; saved during add/update/remove, and committed when submitting.

const [changes, setChanges] = useState({});

...

const addFormFields = () => {
  const newItem = {
    orderno: orderNumber,
    inputValue1: "",
    inputValue2: "",
    checked: false,
    type: "add"
  };

  setFormValues((values) => [...values, newItem]);
  setChanges((changes) => ({
    ...changes,
    [newItem.orderno]: newItem
  }));
  setOrderNumber((prev) => prev + 1);
};

const removeFormFields = (index) => {
  const item = {
    ...formValues[index],
    type: "remove"
  };

  setFormValues((values) => values.filter((el, i) => i !== index));
  setChanges((changes) => ({
    ...changes,
    [item.orderno]: item
  }));
};

const onChangeFieldValue = (index, key, value) => {
  const item = {
    ...formValues[index],
    [key]: value,
    type: "edit"
  };

  setFormValues((prevState) => {
    if (value?.length > 0) {
      setError(false);
      const copyState = [...prevState];
      copyState[index] = item;
      return copyState;
    } else {
      setError(true);
      return prevState;
    }
  });
  setChanges((changes) => ({
    ...changes,
    [item.orderno]: item
  }));
};

const saveFields = (e) => {
  const queryparam = {
    inputData: Object.values(changes)
  };
  console.log("Changes to commit", queryparam);
  setChanges({});
};

Edit sending-only-the-updated-newly-created-records-to-api-in-react-hooks