Input Text unfocuses after each character is typed in, but it seems to be a target issue within React

I am creating a table using Material UI Table. I want to populate by fetching from api, which seems fine. Now, each row should display two buttons, one for removing that row by using the filter() method. And the other to modify the title.

For removing the row, I’m targeting the button’s parent ID which (the TableRow ID) and I’m filtering all the elements of the array whose index does not match the TableRow ID, this seems to be working fine, only thing is I have to use id - 1 so it matches the index number. That seems to be working fine.

For the editing of the title I’m having some issues. Here’s the step by step process:

  1. The Edit button toggles the disable value in the input so it becomes ‘editable’. The handleClickEdit function sets new state for data so the input is enabled.

  2. The input’s onChange runs the handleChange() function, this creates a new array and based on the id - 1 (like on the remove function) as an the index, it sets the title property of that object and then sets that new Array as the new state value for data. **One issue here is that on any character input the input field is unfocused and you have to click again to continue typing. Note that this doesn’t happen if I use id instead of id - 1, but it changes the field below. **

  3. The value is stored on state and when Done button is clicked, the handleDone function toggles the input field to disabled again.

  4. An extra and annoying issue of this approach is that if you remove a row, and then want to edit a row below the one that was removed, the edit targets the row below instead of that actual row.

Here’s my code:

import React, { useEffect, useState } from "react";
import "./App.css";

import {
  TablePagination,
  Table,
  TableBody,
  TableFooter,
  TableContainer,
  TableRow,
  TableHead,
} from "@mui/material";

import TableCell from "@mui/material/TableCell";

function App() {
  const [data, setData] = useState([]);
  const [toggleEdit, setToggleEdit] = useState(false);

  useEffect(() => {
    fetch("https://jsonplaceholder.typicode.com/photos?_limit=5")
      .then((res) => res.json())
      .then((data) => {
        setData(data.map((item) => ({ ...item, enableEdit: true })));
      });
  }, []);

  const removeRow = (e) => {
    const { id } = e.target.parentElement;
    let arr = data.filter((elem) => elem.id != id);
    setData(arr);
  };

  const handleClickEdit = (e) => {
    const { id } = e.target.parentElement;
    setToggleEdit(!toggleEdit);
    let newData = [...data];
    newData[id-1].enableEdit = !newData[id-1].enableEdit;
    setData(newData);
  };

  const handleChange = (e) => {
    const { value, id } = e.target;
    let newData = [...data];
    newData[id-1].title = value;
    setData(newData);
  };

  const handleDone = (e) => {
    const { id } = e.target.parentElement;
    let newData = [...data];
    newData[id-1].enableEdit = !newData[id-1].enableEdit;

    setData(newData);
    console.log(data[id-1]);
  };

  return (
    <div>
      <div className="table-container">
        <TableContainer>
          <Table>
            <TableHead>
              <TableRow>
                <TableCell>ID</TableCell>
                <TableCell>Album ID</TableCell>
                <TableCell>Title</TableCell>
                {/* <TableCell>Thumbnail</TableCell> */}
                <TableCell>Actions</TableCell>
              </TableRow>
            </TableHead>
            <TableBody>
              {data.map((row) => (
                <TableRow id={row.id} key={row.id}>
                  <TableCell key={row.id + "_id"} id={row.id + "_id"}>
                    {row.id}
                  </TableCell>
                  <TableCell>{row.albumId}</TableCell>
                  <TableCell key={row.title} id={row.title}>
                    <input
                      type="text"
                      disabled={row.enableEdit}
                      className="title"
                      defaultValue={row.title}
                      id={row.id}
                      onChange={(e) => handleChange(e)}
                      name={"title"}
                    />
                  </TableCell>
                  {/* <TableCell><img src={row.thumbnailUrl} /></TableCell> */}
                  <TableCell id={row.id}>
                    <button onClick={(e) => removeRow(e)}>Remove</button>
                    {row.enableEdit && (
                      <button onClick={(e) => handleClickEdit(e)}>Edit</button>
                    )}
                    {row.enableEdit === false && (
                      <button onClick={(e) => handleDone(e)}>Done</button>
                    )}
                  </TableCell>
                </TableRow>
              ))}
            </TableBody>
            <TableFooter>
                </TableFooter>
          </Table>
        </TableContainer>
      </div>
    </div>
  );
}

export default App;