Skip to content

Checkbox column without full rerenders. #375

@luap2703

Description

@luap2703

Hey,

I am trying to implement a checkbox column (like selecting rows to delete/update/export.

Unfortunately, the current api design doesn't allow me to do such without rerendering the whole column (see below).

Is this library still maintained and is any update of the "special columns" design in the pipeline?

Great library anyway!

  const [selectedColumns, setSelectedColumns] = React.useState<string[]>([]);

  const checkboxComponent: CellComponent<StockWithAnalyticsFragment, any> = useCallback(
    (props) => {
      // eslint-disable-next-line react-hooks/rules-of-hooks
      const id = useMemo(
        () => props.rowData.productId + "___" + props.rowData.warehouseId,
        [props.rowData.productId, props.rowData.warehouseId],
      );
      // eslint-disable-next-line react-hooks/rules-of-hooks
      const checked = useMemo(() => selectedColumns.includes(id), [id]);

      if (props.rowIndex === 0) {
        console.log("isChecked", props.rowIndex, props.columnIndex, props.rowData);
      }
      return (
        <BaseCheckbox
          checked={checked}
          onCheckedChange={(e) => {
            setSelectedColumns((prev) => {
              if (e) {
                return [...prev, id];
              } else {
                return prev.filter((d) => d !== id);
              }
            });
          }}
        />
      );
    },
    [selectedColumns],
  );

  const selectedColumnsChecked = useMemo(() => {
    return selectedColumns.length === data.length ? true : selectedColumns.length > 0 ? "indeterminate" : false;
  }, [data.length, selectedColumns.length]);
  const onCheckedChange = useCallback(
    (value: boolean) => {
      if (selectedColumns.length === data.length) {
        setSelectedColumns([]);
      } else {
        setSelectedColumns(data.map((d) => d.productId + "___" + d.warehouseId));
      }
    },
    [data, selectedColumns.length],
  );

/*

HERE THE PROBLEM OCCURS (AND ALSO PARTIALLY ABOVE):

Since the state of the select array has to be passed to the column as well as each cell, it rerenders the complete column on each change...


*/
  const gutterColumn: SimpleColumn<StockWithAnalyticsFragment, any> = useMemo(() => {
    return {
      component: checkboxComponent,
      title: <BaseCheckbox checked={selectedColumnsChecked} onCheckedChange={onCheckedChange} />,
    };
  }, [checkboxComponent, onCheckedChange, selectedColumnsChecked]); // <!--- HERE!!!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions