1771 Technologies Logo

Introduction

React Best Practices

Graphite Grid integrates seamlessly with React, adhering closely to React's component and state lifecycle. This guide outlines best practices for effectively using Graphite Grid within your React applications.

Info

This page assumes some basic familiarity with Graphite Grid and its API. If you are brand new to Graphite Grid, consider reading the Quick Start guide first.

Give Each Grid Its Own State

Graphite Grid distinguishes between grid state and grid rendering, enabling the sharing of grid state across multiple components. While it might seem feasible to use the same state object for multiple grid instances, this approach leads to unexpected behaviors as individual grid components may separately update the same grid state.

Don't

function MyGrid() {
  const state = useGraphiteGrid();
 
  return (
    <>
      <GraphiteGridDom state={state} />
      <GraphiteGridDom state={state} />
    </>
  );
}

Do

function MyGrid() {
  const stateA = useGraphiteGrid();
  const stateB = useGraphiteGrid();
 
  return (
    <>
      <GraphiteGridDom state={stateA} />
      <GraphiteGridDom state={stateB} />
    </>
  );
}

Immutable Data

Graphite Grid never mutates the state values directly. Ensure that any data provided to the grid is also treated immutably, especially when dealing with editable data.

Don't

const columns = api.getColumnDefinitionsExn();
 
columns[0].id = "<updated id>";

Do

const columns = api.getColumnDefinitionsExn();
 
const newColumns = [...columns];
newColumns[0] = { ...newColumns[0], id: "<updated id>" };
 
// Or if using ES2023 syntax
const newColumns = columns.with(0, { ...columns[0], id: "<updated id>" });

Clean-Up Event Listeners

When adding event listeners to the Grid, ensure they are properly removed when no longer needed to prevent memory leaks and other side effects.

Don't

useEffect(() => {
  api.addEventListener("onColumnMove", () => {
    // do something
  });
}, [api]);

Do

useEffect(() => {
  const remove = api.addEventListener("onColumnMove", () => {
    // do something
  });
 
  return () => remove();
}, [api]);

useGraphiteGrid Initializes Only Once

useGraphiteGrid, similar to useState, initializes only once. Only the initial values provided will be used for the state. This behavior is consistent with the standard React hook patterns. Attempting to dynamically change the initial state after component mounts will not reinitialize the grid state.

Don't

function MyGrid() {
  const [rowHeight, setRowHeight] = useState(40);
  const state = useGraphiteGrid({
    initial: {
      rowHeight,
      // other props
    },
  });
 
  return (
    <div>
      <button onClick={() => setRowHeight((prev) => prev + 10)}>Increase Row Height</button>
      {/* Other components */}
    </div>
  );
}

Do

function MyGrid() {
  const state = useGraphiteGrid({
    initial: {
      rowHeight: 40,
      // other props
    },
  });
 
  return (
    <div>
      <button onClick={() => state.api.setRowHeight(state.api.getRowHeight() + 10)}>
        Increase Row Height
      </button>
      {/* Other components */}
    </div>
  );
}