React повторно отображает таблицу в новом порядке

#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)}
]
  

Однако вместо этого компонент загружает новый блок в конце.

Блок # 8 помещается в конец списка таблиц блоков, а не в начало

Я чувствую, что проблема заключается в том, как отображаются таблицы html, и поэтому попытка добавить новые данные в установленную таблицу требует манипулирования DOM. Я не уверен, как поступить. Любая помощь будет принята с благодарностью.

Ответ №1:

Ну, я создал песочницу, и она работает просто отлично. Проблема была связана с логикой, и вам просто нужно найти индекс blockNum перед вставкой.

Комментарии:

1. но это не объясняет, как серверное состояние правильно добавляет новое значение массива на основе blockNum, а затем отображает его по-другому. Например, как я указал выше, блок # 8 отображается на серверной части, чтобы показать содержимое блока # 7 перед добавлением нового блока # 1, однако на интерфейсной части Блок # 8 пуст.

2. Теперь я попытался отсортировать массив с помощью .map().sort(), и после того, как это не сработало, я попытался использовать хук useState, где я взял OpenBlocks , отсортировал с помощью .sort(), затем взял результат и поместил его в объект useState, и ВСЕ РАВНО серверная часть вернапри этом интерфейс просто вставляет новые блоки в конец без видимой причины.