Home > front end >  How to update nested data react
How to update nested data react

Time:08-06

I am trying to build a form with some nested data update. The code is as below:

On Change method

let student = {
        name: null,
        marks: { english: null },
    };
const handleChange = (updatedValue) => {
    student = {
        ...student,
        ...updatedValue,
        marks: { ...updatedValue.marks },
    };
    console.log(student);
};

And my JSX:

<input
                            type="text"
                            className="form-control"
                            id="name"
                            placeholder="Name"
                            value={student.name ?? ""}
                            onChange={(event) =>
                                handleChange({
                                    name: event.target.value,
                                })
                            }
                        />
<input
                                type="text"
                                className="form-control"
                                id="english"
                                placeholder="English"
                                value={student.marks.english ?? ""}
                                onChange={(event) =>
                                    handleChange({
                                        marks: { english: event.target.value },
                                    })
                                }
                            />

The problem is that for "name" it works fine. But for "english", it behaves abnormally. E.g. when I enter "1" in English, it updates it to 1 in the console but on the UI, it immediately disappears from the input box. Also if I update it to 2, the value is replaced from one to 2.

The the expected value is 1

Can someone please help me identifying how to update the nested values correctly from the input box?

CodePudding user response:

you must use state to store data

let student = {
    name: null,
    marks: { english: null },
};

change to

const [student, setStudent] = useState({
    name: null,
    marks: { english: null },
});

const handleChange = (updatedValue) => {
  setStudent(student => ({
    ...student,
    ...updatedValue,
    marks: { ...student.marks, ...updatedValue.marks },
  }))
};

CodePudding user response:

try this code and also here is codesandbox

import React, { useState } from "react";

export default function Form({ addStudent }) {
  let [student, setStudent] = useState({
    id: "",
    name: "",
    course: "",
    sem: "",
    marks: { english: "", maths: "", science: "" }
  });
  const handleChange = (value) => {
    const tempStudent = { ...student, ...value };
    setStudent(tempStudent);
  };
  const handleMarksChange = (value) => {
    const tempStudent = { ...student, marks: { ...student.marks, ...value } };
    setStudent(tempStudent);
  };
  return (
    <>
      <form>
        <div className="container form-group">
          <div className="row">
            <div className="col-6">
              <label htmlFor="id" className="ms-2">
                ID
              </label>
              <input
                type="number"
                className="form-control"
                id="id"
                placeholder="ID"
                value={student.id || ""}
                onChange={(event) => {
                  handleChange({ id: event.target.value });
                }}
              />
            </div>
            <div className="col-6">
              <label htmlFor="name" className="ms-2">
                Name
              </label>
              <input
                type="text"
                className="form-control"
                id="name"
                placeholder="Name"
                value={student.name ?? ""}
                onChange={(event) => handleChange({ name: event.target.value })}
              />
            </div>
            <div className="col-6">
              <label htmlFor="course" className="ms-2">
                Course
              </label>
              <input
                type="text"
                className="form-control"
                id="course"
                placeholder="Course"
                value={student.course ?? ""}
                onChange={(event) =>
                  handleChange({
                    course: event.target.value
                  })
                }
              />
            </div>
            <div className="col-6">
              <label htmlFor="sem" className="ms-2">
                Semmester
              </label>
              <input
                type="text"
                className="form-control"
                id="sem"
                placeholder="Semmester"
                value={student.sem ?? ""}
                onChange={(event) => handleChange({ sem: event.target.value })}
              />
            </div>
            <span className="fw-bold mt-2 ms-2">Marks</span>
            <div className="col-6">
              <label htmlFor="maths" className="ms-2">
                Maths
              </label>
              <input
                type="number"
                className="form-control"
                id="maths"
                placeholder="Maths"
                value={student.marks.maths ?? ""}
                onChange={(event) =>
                  handleMarksChange({
                    maths: event.target.value
                  })
                }
              />
            </div>
            <div className="col-6">
              <label htmlFor="English" className="ms-2">
                English
              </label>
              <input
                type="text"
                className="form-control"
                id="english"
                placeholder="English"
                value={student.marks.english ?? ""}
                onChange={(event) =>
                  handleMarksChange({
                    english: event.target.value
                  })
                }
              />
            </div>
            <div className="col-6">
              <label htmlFor="science" className="ms-2">
                Science
              </label>
              <input
                type="science"
                className="form-control"
                id="science"
                placeholder="Science"
                value={student.marks.science ?? ""}
                onChange={(event) =>
                  handleMarksChange({
                    science: event.target.value
                  })
                }
              />
            </div>
          </div>
        </div>
      </form>
    </>
  );
}

Hope this will give you output in your console.

And You need to use state to pass value to the input.

  • Related