В этой статье воспользуемся предыдущими наработками и перепишем код для случая с редактированием ячейки таблицы.
Редактирование ячейки таблицы
Для начала придумаем исходный массив объектов, из которого можно составить таблицу. Получится, что свойства объектов будут значениями ячеек, сами объекты будут содержать информацию в строках. При этом надо не забыть про генерацию уникального id. Получится такой код:const mouseText = [
{id: id(), text1: 'Тише,', text2: 'мыши,', text3: 'кот на крыше'},
{id: id(), text1: 'А котята', text2: 'ещё', text3: 'выше'},
{id: id(), text1: 'Кот', text2: 'пошёл за', text3: 'молоком'},
{id: id(), text1: 'А', text2: 'котята', text3: 'кувырком'},
];
Из такого объекта можно сделать таблицу. В ячейках столбцов будут значения свойств text1, text2, text3. Но вспомним пример из предыдущей статьи: нам нужно как-то отмечать факт редактирования ячейки. То есть у каждого свойства должно быть ещё одно поле с логическим значением true/false. В которое записывается true при клике на ячейку и false после завершения редактирования ячейки таблицы. Поэтому перепишем наш массив, добавив свойства:
const mouseText = [
{
id: id(),
rows: [ // строки
{isEdit: false, prop: 'text1', value: 'Тише,'},
{isEdit: false, prop: 'text2', value: 'мыши,'},
{isEdit: false, prop: 'text3', value: 'кот на крыше'}
]
},
{
id: id(),
rows: [
{isEdit: false, prop: 'text1', value: 'А котята'},
{isEdit: false, prop: 'text2', value: 'ещё'},
{isEdit: false, prop: 'text3', value: 'выше'}
]
},
{
id: id(),
rows: [
{isEdit: false, prop: 'text1', value: 'Кот'},
{isEdit: false, prop: 'text2', value: 'пошёл за'},
{isEdit: false, prop: 'text3', value: 'молоком'}
]
},
{
id: id(),
rows: [
{isEdit: false, prop: 'text1', value: 'А'},
{isEdit: false, prop: 'text2', value: 'котята'},
{isEdit: false, prop: 'text3', value: 'кувырком'}
]
}
];
Теперь при редактировании определённой ячейки таблицы мы сможем выставить ей свойство isEdit в значение true.Логика нашей программы ничем не будет отличаться от той, что описана в предыдущей статье. Поэтому сразу приведём полный пример:
import React, { useState } from 'react';
function App() {
const [objArr, setObjArr] = useState(mouseText);
const rows = objArr.map(obj => {
const cells = obj.rows.map(field => {
let elem;
if (!field.isEdit) {
elem = <span onClick={() => editStart(obj.id, field.prop)}>
{field.value}
</span>;
} else {
elem = <input
value={field.value}
onChange={(event) => change(obj.id, field.prop, event)}
onBlur={() => editEnd(obj.id, field.prop)}
/>;
}
return <td key={field.prop}>{elem}</td>;
});
return <tr key={obj.id}>{cells}</tr>;
});
function editStart(id, prop) {
setObjArr(objArr.map(obj => {
if (obj.id == id) {
const rows = obj.rows.map(field => {
if (field.prop == prop) {
return {...field, isEdit: true}
} else {
return field;
}
});
return {id, rows};
} else {
return obj;
}
}));
}
function editEnd(id, prop) {
setObjArr(objArr.map(obj => {
if (obj.id == id) {
const rows = obj.rows.map(field => {
if (field.prop == prop) {
return {...field, isEdit: false}
} else {
return field;
}
});
return {id, rows};
} else {
return obj;
}
}));
}
function change(id, prop, event) {
setObjArr(objArr.map(obj => {
if (obj.id == id) {
const rows = obj.rows.map(field => {
if (field.prop == prop) {
return {...field, value: event.target.value}
} else {
return field;
}
});
return {id, rows};
} else {
return obj;
}
}));
}
return <div>
<table>
<tbody>
{rows}
</tbody>
</table>
</div>;
}
export default App;