Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

how to Control Dynamic Input fields with react js usestate

I have this JSON data to loop through the object and generate an input field based on the provide_no or provide_remark value as "Y".

I have successfully looped through the object and generated dynamic input fields.

My main problem is I can’t control the dynamic input field value.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

JSON Data :

const jsonData = [
  {
    id: 1,
    name: "Item One",
    provide_no: "Y",
    provide_remark: "N",
  },
  {
    id: 2,
    name: "Item One",
    provide_no: "Y",
    provide_remark: "Y",
  },
  {
    id: 3,
    name: "Item One",
    provide_no: "Y",
    provide_remark: "N",
  },
  {
    id: 4,
    name: "Item One",
    provide_no: "Y",
    provide_remark: "Y",
  },
];

My Component :

const Some = () => {
  const [init, setInit] = useState({
    id: 0,
    count: 0,
    count2: 0,
  });

  const handelChangeCount = (e) => {
    setInit({ ...init, id: e.target.id, count: e.target.value }); // this will change the all value of init state
  };
  const handelChangeCount2 = (e) => {
    setInit({ ...init, id: e.target.id, count2: e.target.value }); // this will change the all value of init state
  };

  return jsonData.map((d) => (
    <div key={d.id}>
      {d.provide_no === "Y" && (
        <input
          className="input w-auto"
          type="number"
          value={init.count}
          id={d.id}
          name="count"
          onChange={(event) => handelChangeCount(event)}
        />
      )}
      {d.provide_remark === "Y" && (
        <input
          className="input w-auto"
          type="number"
          value={init.count2}
          id={d.id}
          name="count2"
          onChange={(event) => handelChangeCount2(event)}
        />
      )}
    </div>
  ));
};
export default Some;

I have tried to change the init state with handelChangeCount & handelChangeCount2 function

  const handelChangeCount = (e) => {
    setInit({ ...init, id: e.target.id, count: e.target.value }); // this will change the all value of init state
  };
  const handelChangeCount2 = (e) => {
    setInit({ ...init, id: e.target.id, count2: e.target.value }); // this will change the all value of init state
  };

>Solution :

It seems like you are facing an issue with controlling the values of the dynamic input fields generated based on the JSON data. The problem lies in how you are updating the init state object.

Currently, when you call setInit , you are spreading the existing init state and only updating the specific properties ( count or count2 ) based on the id of the input field. However, this approach is overwriting the entire state object, causing all the input fields to have the same value.

To fix this issue, here’s my code as follows:

const Some = () => {
  const [init, setInit] = useState([]);

  const handleChangeCount = (e) => {
    const { id, value } = e.target;
    setInit((prevInit) =>
      prevInit.map((item) =>
        item.id === parseInt(id) ? { ...item, count: value } : item
      )
    );
  };

  const handleChangeCount2 = (e) => {
    const { id, value } = e.target;
    setInit((prevInit) =>
      prevInit.map((item) =>
        item.id === parseInt(id) ? { ...item, count2: value } : item
      )
    );
  };

  useEffect(() => {
    // Initialize the state with the jsonData
    setInit(jsonData);
  }, []);

  return init.map((d) => (
    <div key={d.id}>
      {d.provide_no === "Y" && (
        <input
          className="input w-auto"
          type="number"
          value={d.count || ""}
          id={d.id}
          name="count"
          onChange={handleChangeCount}
        />
      )}
      {d.provide_remark === "Y" && (
        <input
          className="input w-auto"
          type="number"
          value={d.count2 || ""}
          id={d.id}
          name="count2"
          onChange={handleChangeCount2}
        />
      )}
    </div>
  ));
};

export default Some;

Hope this would solve your problem.
🙂 David

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading