Как я могу обновить только одно значение ячейки и JSON в таблице

Я пишу код, в котором у меня есть таблица из 3 столбцов. последний столбец доступен для редактирования. Мое требование: когда я нажимаю на эту ячейку, добавляю новое значение, и оно должно обновлять соответствующее значение в JSON.

В настоящее время я

  1. Невозможно ввести значение в ячейку (хотя оно доступно для редактирования).
  2. Невозможно узнать, как я могу обновить JSON.

Вот мой код.

import Table from "@mui/material/Table";
import TableBody from "@mui/material/TableBody";
import TableCell from "@mui/material/TableCell";
import TableContainer from "@mui/material/TableContainer";
import TableHead from "@mui/material/TableHead";
import TableRow from "@mui/material/TableRow";
import Paper from "@mui/material/Paper";
import { useEffect } from "react";
const csvArray = [
  { Name: "user 1", Age: "12", Rank: "2" },
  { Name: "user 2", Age: "13", Rank: "3" },
  { Name: "user 3", Age: "10", Rank: "2" },
  { Name: "user 4", Age: "16", Rank: "1" },
  { Name: "user 5", Age: "14", Rank: "5" }
];
const keys = ["Name", "Age", "Rank"];
const RenderTable = () => {
  const handleBlur = (e) => {
    e.currentTarget.classList.add("noBorder");
    e.currentTarget.classList.remove("border");
  };

  useEffect(() => {
    console.log(JSON.stringify(csvArray));
  }, []);

  const handleChange = (e) => {
    e.currentTarget.readOnly = false;
    e.currentTarget.classList.remove("noBorder");
    e.currentTarget.classList.add("border");
    e.preventDefault();
  };

  return (
    <TableContainer component={Paper}>
      <Table sx={{ minWidth: 650 }} aria-label="simple table">
        <TableHead>
          <TableRow>
            {keys.map((item, idx) => (
              <TableCell key={idx}>{item}</TableCell>
            ))}
          </TableRow>
        </TableHead>
        <TableBody>
          {csvArray.map((item, idx) => (
            <TableRow>
              {keys.map((key, idx) =>
                key === "Rank" ? (
                  <TableCell>
                    <input
                      class="noBorder"
                      type="true"
                      readOnly="true"
                      value={item[key]}
                      onBlur={(e) => handleBlur(e)}
                      onClick={(e) => handleChange(e)}
                    ></input>
                  </TableCell>
                ) : (
                  <TableCell> {item[key]} </TableCell>
                )
              )}
            </TableRow>
          ))}
        </TableBody>
      </Table>
    </TableContainer>
  );
};

export default RenderTable;

Вот он в действии https://codesandbox.io/s/wandering-pine-pddi4l?file=/src/RenderTable.js:0-2161. Где я ошибаюсь и как это исправить?

Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
Приложение для отслеживания бюджета на React js для начинающих
Приложение для отслеживания бюджета на React js для начинающих
Обучение на практике - это проверенная тема для достижения успеха в любой области. Если вы знаете контекст фразы "Практика делает человека...
Стоит ли использовать React в 2022 году?
Стоит ли использовать React в 2022 году?
В 2022 году мы все слышим о трендах фронтенда (React, Vue), но мы не знаем, почему мы должны использовать эти фреймворки, когда их использовать, а...
Как передать состояние или данные в react-router v6
Как передать состояние или данные в react-router v6
react-router - это лучшая библиотека для работы с маршрутизацией в reactjs. С помощью react-router вы передаете состояние или данные от одного...
0
0
56
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я добавил состояние csvArrayState для управления изменениями. Проблема, с которой вы столкнулись, относится к контролю. Да, вы изменили тип и сделали ранги редактируемыми, но вам не хватило контроля. Этот фрагмент добавляет этот элемент управления.

import Table from "@mui/material/Table";
import TableBody from "@mui/material/TableBody";
import TableCell from "@mui/material/TableCell";
import TableContainer from "@mui/material/TableContainer";
import TableHead from "@mui/material/TableHead";
import TableRow from "@mui/material/TableRow";
import Paper from "@mui/material/Paper";
import { useState } from "react";
const csvArray = [
  { Name: "user 1", Age: "12", Rank: "2" },
  { Name: "user 2", Age: "13", Rank: "3" },
  { Name: "user 3", Age: "10", Rank: "2" },
  { Name: "user 4", Age: "16", Rank: "1" },
  { Name: "user 5", Age: "14", Rank: "5" }
];
const keys = ["Name", "Age", "Rank"];
const RenderTable = () => {

  const [csvArrayState, setCsvArrayState] = useState(() => 
    csvArray);

  const handleBlur = (e) => {
    e.currentTarget.classList.add("noBorder");
    e.currentTarget.classList.remove("border");
    console.log(JSON.stringify(csvArrayState));
  };

  const handleChange = (e) => {
    e.preventDefault();
    e.currentTarget.readOnly = false;
    e.currentTarget.classList.remove("noBorder");
    e.currentTarget.classList.add("border");
  };

  return (
    <TableContainer component={Paper}>
      <Table sx={{ minWidth: 650 }} aria-label="simple table">
        <TableHead>
          <TableRow>
            {keys.map((item, idx) => (
              <TableCell key={idx}>{item}</TableCell>
            ))}
          </TableRow>
        </TableHead>
        <TableBody>
          {csvArray.map((item, i) => (
            <TableRow>
              {keys.map((key, idx) =>
                key === "Rank" ? (
                  <TableCell>
                    <input
                      class="noBorder"
                      type="true"
                      readOnly="true"
                      value={csvArrayState[i].Rank}
                      onChange={(e) => {
                        const updatedRankFields = csvArrayState.map((r, rIdx) => {
                          if (rIdx === i) {
                            return { ...r, Rank: e.target.value };
                          } else {
                            return r;
                          }
                        });
                        setCsvArrayState(updatedRankFields);
                      }}
                      onBlur={(e) => handleBlur(e)}
                      onClick={(e) => handleChange(e)}
                    ></input>
                  </TableCell>
                ) : (
                  <TableCell> {item[key]} </TableCell>
                )
              )}
            </TableRow>
          ))}
        </TableBody>
      </Table>
    </TableContainer>
  );
};

export default RenderTable;

Спасибо за этого дружище. Я могу редактировать данные ранга, но я не думаю, что данные обновляются :( . Я проверил это, добавив console.log(JSON.stringify(csvArray)) внутри handleBlur().

Rakesh 23.04.2022 15:19

@ Ракеш Рад, что могу быть полезен. Я отредактировал код. Я думаю, что handleBlur() теперь должен регистрировать весь csvArray с обновленным полем ранга.

emre-ozgun 23.04.2022 15:51

Обратите внимание, что манипулируется csvArrayState. Не ваш оригинальный csvArray. Так что я регистрирую это.

emre-ozgun 23.04.2022 16:01

Ты классный друг :-). последний вопрос, который у меня есть, это то, что я получаю предупреждение Warning: Each child in a list should have a unique "key" prop. Здесь я использую idx для зацикливания (надеюсь, я делаю это правильно).

Rakesh 23.04.2022 19:27

Здоровья, приятель. Я бы сказал, что это потому, что TableRow не использует никакой ключ, но я не совсем знаком с MUI, так что это на вас :)

emre-ozgun 23.04.2022 21:06

Другие вопросы по теме