1

I'm trying to perform CRUD operations in React using react-table-6 library, since its lightweight and has basic functionalities. I dont want my bundle size to be more.

Here is my Code https://codesandbox.io/s/crud-using-react-table-6-rs2r9

Whenever I try to edit and change values using input, the table re-renders. I think the issue is because, the Cell inside the columns re-renders when I change the state. But I'm not able to get a workaround for this. Any help would be appreciated greatly. Thanks.

Andruraj
  • 67
  • 2
  • 11

1 Answers1

3

I did some experiments and found that, react-table-6 library doesn't support input element.

However with contentEditable div, It seems to work perfectly.

Code with Input

import React from "react";
import "./styles.css";
import ReactTable from "react-table-6";
import "react-table-6/react-table.css";

export default function App() {
  const [state, setState] = React.useState({
    data: [
      {
        name: "Adam",
        age: 20
      },
      {
        name: "Eve",
        age: 19
      },
      {
        name: "Abel",
        age: 4
      },
      {
        name: "Coin",
        age: 5
      }
    ],
    edit: {}
  });

  return (
      <ReactTable
        data={state.data}
        columns={[
          {
            Header: "Name",
            accessor: "name",
            Cell: ({ value, ...props }) =>
              state.edit.name === props.original.name ? (
                <input
                  value={state.edit.name}
                  onChange={(e) => {
                    console.log(e.target.value);
                    setState({
                      ...state,
                      edit: { ...state.edit, name: e.target.value }
                    });
                  }}
                />
              ) : (
                value
              )
          },
          {
            Header: "Age",
            accessor: "age"
          },
          {
            Cell: ({ value, ...props }) =>
              Object.keys(state.edit).length > 0 &&
              state.edit.name === props.original.name ? (
                <button>Save</button>
              ) : (
                <button
                  onClick={(e) => setState({ ...state, edit: props.original })}
                >
                  Edit
                </button>
              )
          }
        ]}
      />
  );
}

Code with content editable div

import React from "react";
import "./styles.css";
import ReactTable from "react-table-6";
import "react-table-6/react-table.css";

export default function App() {
  const [state, setState] = React.useState({
    data: [
      { id: 1, name: "Adam", age: 20 },
      { id: 2, name: "Eve", age: 19 },
      { id: 3, name: "Abel", age: 4 },
      { id: 4, name: "Coin", age: 5 }
    ],
    edit: {}
  });

  return (
    <ReactTable
      data={state.data}
      columns={[
        {
          Header: "Name",
          accessor: "name",
          Cell: ({ value, ...props }) => (
            <div
              style={
                state.edit.id === props.original.id
                  ? {
                      backgroundColor: "#ddd",
                      padding: "5px",
                      outline: "1px solid #0000ff"
                    }
                  : {}
              }
              contentEditable={state.edit.id === props.original.id}
              suppressContentEditableWarning
              onBlur={(e) => {
                setState({
                  ...state,
                  edit: { ...state.edit, name: e.target.innerHTML }
                });
              }}
              dangerouslySetInnerHTML={{
                __html:
                  state.edit.id === props.original.id ? state.edit.name : value
              }}
            />
          )
        },
        {
          Header: "Age",
          accessor: "age"
        },
        {
          Cell: ({ value, ...props }) =>
            Object.keys(state.edit).length > 0 &&
            state.edit.id === props.original.id ? (
              <button
                onClick={(e) => {
                  let newdata = state.data;
                  newdata.map((d) => {
                    if (d.id === state.edit.id) {
                      d.name = state.edit.name;
                    }
                    return d;
                  });
                  console.log(newdata);
                  setState({ ...state, data: newdata, edit: {} });
                }}
              >
                Save
              </button>
            ) : (
              <button
                onClick={(e) => setState({ ...state, edit: props.original })}
              >
                Edit
              </button>
            )
        }
      ]}
      defaultPageSize={5}
    />
  );
}

Andruraj
  • 67
  • 2
  • 11