#javascript #reactjs #html-table #rendering
#javascript #reactjs #html-таблица #рендеринг
Вопрос:
Я разработал компонент React, который представляет список задач для зоомагазина в блочном формате, чтобы пользователи могли упорядочивать задачи в блоках категорий, а не просто список неорганизованных задач. Вы можете добавить блок в начале, в любом месте в середине или в конце списка блоков, и это правильно работает в серверной части, однако при тестировании функции добавления вместо добавления блоков везде, где вы выбрали, my table последовательно добавляет их в конец таблицы, даже если вкомпонент указывает правильный порядок.
Вот код компонента:
import React, { useEffect, useContext, Fragment } from 'react';
import ManagerContext from '../../../context/manager/managerContext';
import M from 'materialize-css';
import Todo from './Todo';
const Open = () => {
const managerContext = useContext(ManagerContext);
const {
openBlocks,
openTodos,
addNewBlock,
} = managerContext;
useEffect(() => {
M.AutoInit();
// eslint-disable-next-line
}, [openBlocks]);
return (
<div>
<h2>Opening Tasks</h2>
<table>
<tbody>
{openBlocks !== null amp;amp;
openBlocks.map((block) => (
<Fragment key={block.blockNum}>
<tr>
<td className="filler">
<button
className="btn btn-primary btn-block"
onClick={() => {
addNewBlock('Open', block.blockNum, openBlocks);
}}
>
{block.blockNum === 1
? `Add new block above Block #${block.blockNum}`
: `Add new block between Block #${
block.blockNum - 1
} amp; Block #${block.blockNum}`}
</button>
</td>
<td className="filler" colSpan="2"></td>
</tr>
<tr>
<td className="block-filler text-center">
<b>Block #{block.blockNum}</b>
</td>
<td className="block-filler text-center" colSpan="2">
<button className="btn btn-danger">Remove Block</button>
</td>
</tr>
<tr>
<th>Description</th>
<th>Category</th>
<th></th>
</tr>
{openBlocks.map((b) =>
b.todos.map(
(todo) =>
todo.block === block.blockNum amp;amp; (
<Todo key={todo.id} todo={todo} />
)
)
)}
<tr>
<td className="filler">
<select name="addToBlock" id="addToBlock" defaultValue="">
<option value="" disabled>
Assign To-Do to Block #{block.blockNum}
</option>
{openTodos !== null amp;amp;
openTodos.map(
(t) =>
t.block === 0 amp;amp; (
<option key={t.id} value={t.id}>
{t.todo} ({t.category} Task)
</option>
)
)}
</select>
</td>
<td className="filler" colSpan="2"></td>
</tr>
{block.blockNum === openBlocks.length amp;amp; (
<tr>
<td className="filler">
<button className="btn btn-primary btn-block">
Add new block below Block #{block.blockNum}
</button>
</td>
<td className="filler" colSpan="2"></td>
</tr>
)}
</Fragment>
))}
</tbody>
</table>
</div>
);
};
export default Open;
Вот состояние openBlocks
при загрузке данных из серверной части:
[
{blockNum: 1, todos: Array(1)}
{blockNum: 2, todos: Array(4)}
{blockNum: 3, todos: Array(2)}
{blockNum: 4, todos: Array(1)}
{blockNum: 5, todos: Array(2)}
{blockNum: 6, todos: Array(6)}
{blockNum: 7, todos: Array(1)}
]
Вот компонент в браузере:
Как вы можете видеть, он загружает содержимое openBlocks
в последовательно пронумерованные блоки.
При использовании кнопки «Добавить новый блок над блоком № 1» он отображается в начальном состоянии правильно:
[
{blockNum: 1, todos: Array(0)}
{blockNum: 2, todos: Array(1)}
{blockNum: 3, todos: Array(4)}
{blockNum: 4, todos: Array(2)}
{blockNum: 5, todos: Array(1)}
{blockNum: 6, todos: Array(2)}
{blockNum: 7, todos: Array(6)}
{blockNum: 8, todos: Array(1)}
]
Однако вместо этого компонент загружает новый блок в конце.
Я чувствую, что проблема заключается в том, как отображаются таблицы html, и поэтому попытка добавить новые данные в установленную таблицу требует манипулирования DOM. Я не уверен, как поступить. Любая помощь будет принята с благодарностью.
Ответ №1:
Ну, я создал песочницу, и она работает просто отлично. Проблема была связана с логикой, и вам просто нужно найти индекс blockNum
перед вставкой.
Комментарии:
1. но это не объясняет, как серверное состояние правильно добавляет новое значение массива на основе blockNum, а затем отображает его по-другому. Например, как я указал выше, блок # 8 отображается на серверной части, чтобы показать содержимое блока # 7 перед добавлением нового блока # 1, однако на интерфейсной части Блок # 8 пуст.
2. Теперь я попытался отсортировать массив с помощью .map().sort(), и после того, как это не сработало, я попытался использовать хук useState, где я взял OpenBlocks , отсортировал с помощью .sort(), затем взял результат и поместил его в объект useState, и ВСЕ РАВНО серверная часть вернапри этом интерфейс просто вставляет новые блоки в конец без видимой причины.