Home > Blockchain >  how to update individual array element in side array of object in setState in react js
how to update individual array element in side array of object in setState in react js

Time:11-09

I am trying to add an array element inside the object but if I type text all the text boxes show the text and the text is added only to the first element . even if i added text in second and third text box it is addding into the first tag list plz help me how to fix it

import React, { useState } from "react";

export default function App() {
  const synonym = [
    { id: 1, keyword: "Caffeine", synonyms: ["Coffee", "Espresso"] },
    { id: 2, keyword: "Drowsiness", synonyms: ["Sleeping", "Fatigue"] },
    { id: 3, keyword: "Drowsiness", synonyms: [""] }
  ];
  const [mysynonyms, setSynonyms] = useState(() => synonym);
  const [addTagValue, setAddTagValue] = useState([]);
  const handleChange = (e) => {
    setAddTagValue(e.target.value);
  };
  const handleClick = () => {
    setSynonyms((prevValue) => {
      return prevValue.map((item, itemIndex) => {
        if (itemIndex === 0) {
          return { item, synonyms: [...item.synonyms, addTagValue] };
        } else {
          return item;
        }
      });
    });
    setAddTagValue("");
  };
  return (
    <div className="App">
      {mysynonyms.map((item, cid) => {
        return (
          <>
            <p>{item.keyword}</p>

            {item.synonyms.map((item, cid) => (
              <span
                style={{ border: "1px solid red", padding: "1px 1px 5px 7px" }}
              >
                {item} x
              </span>
            ))}
            <div>
              <input
                value={addTagValue}
                className="form-control bg-color2 text-color7 border-end-0 fs-14 fw-bold"
                type="text"
                onChange={handleChange}
              />
              <button onClick={handleClick}>add tag</button>
            </div>
          </>
        );
      })}
    </div>
  );
}

CodePudding user response:

Here are my updates.

App.js

import React, { useState } from "react";

export default function App() {
  const synonym = [
    { id: 1, keyword: "Caffeine", synonyms: ["Coffee", "Espresso"] },
    { id: 2, keyword: "Drowsiness", synonyms: ["Sleeping", "Fatigue"] },
    { id: 3, keyword: "Drowsiness", synonyms: [""] }
  ];
  const [mysynonyms, setSynonyms] = useState(() => synonym);
  const [addTagValue, setAddTagValue] = useState([]);
  const [editingIndex, setEditingIndex] = useState(0);  // THIS CONTAINS THE INDEX OF EDITING ITEM
  const handleChange = (e, index) => {
    setAddTagValue(e.target.value);
    setEditingIndex(index)  // SAVE THE INDEX OF EDITING ITEM
  };
  const handleClick = () => {
    setSynonyms((prevValue) => {
      return prevValue.map((item, itemIndex) => {
        if (itemIndex === editingIndex) {  // IF CURRENT ITEM IS EDITING, ADD VALUE TO THIS ITEM
          return { ...item, synonyms: [...item.synonyms, addTagValue] };
        } else {
          return item;
        }
      });
    });
    setAddTagValue("");
  };
  return (
    <div className="App">
      {mysynonyms.map((synonymItem, synonymIndex) => {
        return (
          <div key={synonymIndex}>
            <p>{synonymItem.keyword}</p>

            {synonymItem.synonyms.map((item, cid) => (
              <span
                key={cid}
                style={{ border: "1px solid red", padding: "1px 1px 5px 7px" }}
              >
                {item} x
              </span>
            ))}
            <div>
              <input
                value={synonymIndex === editingIndex? addTagValue : ""}
                className="form-control bg-color2 text-color7 border-end-0 fs-14 fw-bold"
                type="text"
                onChange={(e) => handleChange(e, synonymIndex)}
              />
              <button onClick={handleClick}>add tag</button>
            </div>
          </div>
        );
      })}
    </div>
  );
}

And don't forget to use the key attribute for the mapping React Element.

You can check the running code in my CodeSandbox.

CodePudding user response:

I have updated few in your code

<button onClick={() => handleClick(cid)}>add tag</button>

and your function

const handleClick = (tagIndex) => {
    setSynonyms((prevValue) => {
      return prevValue.map((item, itemIndex) => {
        if (itemIndex === tagIndex) {
          return { item, synonyms: [...item.synonyms, addTagValue] };
        } else {
          return item;
        }
      });
    });
    setAddTagValue("");
  };

Please check your coding function as per below

import React, { useState } from "react";

export default function App() {
  const synonym = [
    { id: 1, keyword: "Caffeine", synonyms: ["Coffee", "Espresso"] },
    { id: 2, keyword: "Drowsiness", synonyms: ["Sleeping", "Fatigue"] },
    { id: 3, keyword: "Drowsiness", synonyms: [""] }
  ];
  const [mysynonyms, setSynonyms] = useState(() => synonym);
  const [addTagValue, setAddTagValue] = useState([]);
  const handleChange = (e) => {
    setAddTagValue(e.target.value);
  };
  const handleClick = (tagIndex) => {
    setSynonyms((prevValue) => {
      return prevValue.map((item, itemIndex) => {
        if (itemIndex === tagIndex) {
          return { item, synonyms: [...item.synonyms, addTagValue] };
        } else {
          return item;
        }
      });
    });
    setAddTagValue("");
  };
  return (
    <div className="App">
      {mysynonyms.map((item, cid) => {
        return (
          <>
            <p>{item.keyword}</p>

            {item.synonyms.map((item, cid) => (
              <span
                style={{ border: "1px solid red", padding: "1px 1px 5px 7px" }}
              >
                {item} x
              </span>
            ))}
            <div>
              <input
                value={addTagValue}
                className="form-control bg-color2 text-color7 border-end-0 fs-14 fw-bold"
                type="text"
                onChange={handleChange}
              />
              <button onClick={() => handleClick(cid)}>add tag</button>
            </div>
          </>
        );
      })}
    </div>
  );
}
  • Related