Тернарное выражение не обновляет шаблон jsx - PullRequest
0 голосов
/ 26 февраля 2020

Я использую response- bootstrap -table-2 для создания таблицы, в которой я хочу, чтобы пользователь мог изменять столбцы в модальном пользовательском интерфейсе.

Когда пользователь удаляет столбец изменение не должно вступать в силу до тех пор, пока модальное окно не будет закрыто, поэтому до тех пор я хочу, чтобы пользовательский интерфейс отражал, что столбец будет удален зачеркнутой строкой. Итак, у меня есть троичное выражение на col.deleted, которое показывает текст с зачеркнутым, если true.

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

<tbody>
  {columns.map((col: any, i: number) => (
    <tr key={i}>
      <td>{col.deleted ? <del>{col.text}</del> : col.text}</td>
      <td className="w-20">
        <div className="flex flex-row justify-center">
          <Button
            variant="danger"
            onClick={() => {
              col.deleted = !col.deleted;
              setColumns(columns);
            }}
          >
            <FaTrash />
          </Button>
        </div>
      </td>
    </tr>
  ))}
</tbody>

Я установил columns[i].deleted на true с помощью кнопки, но в пользовательском интерфейсе ничего не обновляется. Я что-то не так понял?

Проверьте эту песочницу для полного примера: https://codesandbox.io/s/silly-wilbur-q3ytt

1 Ответ

1 голос
/ 26 февраля 2020

Вероятно, проблема в том, что вы мутируете государством. Попробуйте let newColums = [...columns]; и затем выполните те же действия, но на newColumn s, а не столбцы , и установите newColumns в setState
У меня недавно была такая же проблема с более простой пример, и это сводилось к тому, что я изменял состояние, и, таким образом, компонент setState не обновлял компонент EDIT пример

// Your onClick function
(i) => {
    let newColumns = [...columns];
    newColumns[i].deleted = !newColumns[i].deleted;
    setState(newColumns);
}

Ваша функция должна выглядеть примерно так, просто отрегулируйте код в случае, если я сделал опечатку
Песочница протестирована

import React, { useState } from "react";
import Button from "react-bootstrap/Button";
import Modal from "react-bootstrap/Modal";
import Table from "react-bootstrap/Table";
// @ts-ignore
import cellEditFactory from "react-bootstrap-table2-editor";
// @ts-ignore
import BootstrapTable from "react-bootstrap-table-next";
import { FaTrash, FaEdit, FaPlus } from "react-icons/fa";
import { rows, columns as cols } from "./data";
import "react-bootstrap-table-next/dist/react-bootstrap-table2.min.css";
import "bootstrap/dist/css/bootstrap.min.css";

export interface ColumnItem {
  dataField: string;
  text: string;
  deleted: boolean;
}

const EditTableModal = (props: any) => {
  const [columns, setColumns] = useState<ColumnItem[]>(
    props.columns.map((col: any) => {
      col.deleted = false;
      return col;
    })
  );

  const handleClick = i => {
    let newColumns = [];
    columns.forEach(column => newColumns.push(Object.assign({}, column)));
    console.log(newColumns);
    console.log(i);
    newColumns[i].deleted = !newColumns[i].deleted;
    console.log(newColumns[i].deleted);
    setColumns(newColumns);
  };
  return (
    <Modal
      {...props}
      size="lg"
      aria-labelledby="contained-modal-title-vcenter"
      centered
    >
      <Modal.Header closeButton>
        <Modal.Title id="contained-modal-title-vcenter">
          <div className="flex flex-row items-center">
            <FaEdit className="mr-2" /> Edit columns
          </div>
        </Modal.Title>
      </Modal.Header>
      <Modal.Body>
        <Table striped bordered hover size="sm" className="mb-0">
          <tbody>
            {columns.map((col: any, i: number) => (
              <tr key={i}>
                <td>{col.deleted ? <del>{col.text}</del> : col.text}</td>
                <td className="w-20">
                  <div className="flex flex-row justify-center">
                    <Button variant="danger" onClick={() => handleClick(i)}>
                      <FaTrash />
                    </Button>
                  </div>
                </td>
              </tr>
            ))}
            <tr>
              <td>
                <div>
                  <Button variant="dark">
                    <FaPlus />
                  </Button>
                </div>
              </td>
              <td className="w-20" />
            </tr>
          </tbody>
        </Table>
      </Modal.Body>
      <Modal.Footer>
        <Button variant="dark" onClick={props.onHide}>
          Save
        </Button>
        <Button variant="light" onClick={props.onHide}>
          Close
        </Button>
      </Modal.Footer>
    </Modal>
  );
};

const ComponentList = () => {
  const [columns] = useState<ColumnItem[]>(cols);
  const [data] = useState<any[]>(rows);
  const [modalShow, setModalShow] = useState(false);

  return (
    <div className="flex flex-col items-center m-3">
      {data.length > 0 ? (
        <div className="flex flex-col items-center">
          <div className="flex flex-row m-2">
            <Button
              variant="dark"
              onClick={() => setModalShow(true)}
              className="ml-1"
            >
              <div className="flex flex-row items-center">
                <FaEdit className="mr-2" /> Edit table
              </div>
            </Button>
            <EditTableModal
              show={modalShow}
              onHide={() => setModalShow(false)}
              backdrop={"static"}
              columns={columns}
            />
          </div>
          <BootstrapTable
            keyField="idInternal"
            data={data}
            columns={columns}
            cellEdit={cellEditFactory({
              mode: "click",
              blurToSave: true,
              autoSelectText: true
            })}
          />
        </div>
      ) : (
        <div className="font-mono text-sm">No data in table</div>
      )}
    </div>
  );
};

export default ComponentList;

...