【问题标题】:React re-rendering table in new order以新顺序反应重新渲染表
【发布时间】:2020-11-11 23:40:06
【问题描述】:

我设计了一个 React 组件,它以块格式显示宠物商店的待办事项列表,以便用户可以在类别块中组织待办事项,而不仅仅是无组织的待办事项列表。您可以在块列表的开头、中间或末尾的任何位置添加块,这在后端可以正常工作,但是,在测试添加功能时,而不是在您选择的任何地方添加块,我的表始终如一将它们添加到表格底部即使在组件状态下顺序正确。

这是组件代码:

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 &&
            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
                          } & 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 && (
                          <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 &&
                        openTodos.map(
                          (t) =>
                            t.block === 0 && (
                              <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 && (
                  <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 的内容加载到按顺序编号的块中。

当使用“在Block #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)}
]

但是,组件会在 end 处加载新块。

我觉得问题在于如何呈现 html 表,因此尝试将新数据添加到已建立的表中需要操作 DOM。我不确定如何进行。任何帮助将不胜感激。

【问题讨论】:

    标签: javascript reactjs html-table rendering


    【解决方案1】:

    我做了一个sandbox,它工作得很好。问题与逻辑有关,您只需在插入前通过blockNum 找到索引即可。

    【讨论】:

    • 但这并不能解释后端状态如何根据 blockNum 正确添加新的 Array 值,然后以不同的方式显示它。例如,正如我上面提供的,Block #8 在后端显示 Block #7 在添加新 Block #1 之前的内容,但是在前端 Block #8 是空白的。
    • 我现在尝试使用 .map().sort() 对数组进行排序,之后我尝试使用使用 openBlocks 的 useState 挂钩,使用 .sort() 进行排序然后将结果放入一个 useState 对象中,但后端仍然是正确的,前端只是在末尾无缘无故地添加新块。
    猜你喜欢
    • 1970-01-01
    • 2016-07-13
    • 2022-01-04
    • 2019-12-13
    • 2018-12-16
    • 1970-01-01
    • 1970-01-01
    • 2019-06-05
    • 2020-03-08
    相关资源
    最近更新 更多