Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

input text field for a particular item in array while mapping?

Im trying to map over an array and trying to update a particular item based on a button click.

<div className="read-data">
    {readData.length >= 1 ? readData.map((res)=>(
     <div>
     <h2>{res.data.message}</h2>
     <button onClick={()=>{
          (setUpdateBox(true))
       }}>
       Update
     </button>
     {updateBox ? (
        <div>
          <form>
            I<input type="text" name="textarea" placeholder="Update message"/>
          </form>
        </div>
     ):null}
      <button onClick={()=>{
        deleteMessage(res)}}> Delete</button>
      </div>
    )):null}
  </div>

it opens text area for every item in array. but i want input text box for the only item whos corresponding button is clicked. plz help how to do it.

like image 890
Mahmood Ahmed Khan Avatar asked Mar 01 '26 06:03

Mahmood Ahmed Khan


1 Answers

you may find that solution useful for you.

  • you need to set a unique index or any identifier to every element.
  • on every update or delete operation, you can access the element by its index
  • reference the input to get the value by using ref

I assume that you pass an array of object as a props

const readData = [
  {
    data: {
      message: "new message 1"
    }
  },
  {
    data: {
      message: "new message 2"
    }
  },
  {
    data: {
      message: "new message 3"
    }
  },
  {
    data: {
      message: "new message 4"
    }
  }
];

ReadData Component

function ReadDataComponent({readData}) {
  let inputRef = React.useRef();

  const [updateBox, setUpdateBox] = React.useState(readData);

  const deleteMessage = (i) => {
    const updatedBox = [...updateBox];
    let filteredBox = updatedBox.filter((_, index) => i !== index);
    setUpdateBox(filteredBox);
  };

  const showUpdateBox = (i) => {
    const updatedBox = [...updateBox];
    updatedBox[i].isOpen = updatedBox[i].isOpen ? !updatedBox[i].isOpen : true;
    updatedBox[i].data.message = inputRef.current
      ? inputRef.current.value
      : updatedBox[i].data.message;
    setUpdateBox(updatedBox);
  };

  return (
    <div className="read-data">
      {readData.length >= 1
        ? updateBox.map((res, i) => (
            <div key={i}>
              <h2>{res.data.message}</h2>
              <button
                onClick={() => {
                  showUpdateBox(i);
                }}
              >
                Update
              </button>
              {res.isOpen ? (
                <div>
                  <form>
                    <input
                      ref={inputRef}
                      type="text"
                      name="textarea"
                      placeholder="Update message"
                    />
                  </form>
                </div>
              ) : null}
              <button
                onClick={() => {
                  deleteMessage(i);
                }}
              >
                {" "}
                Delete
              </button>
            </div>
          ))
        : null}
    </div>
  );
}

live demo

like image 158
samehanwar Avatar answered Mar 02 '26 18:03

samehanwar