Thomas Olef
Thomas Olef

Reputation: 1

React material table dynamic columns not working

im trying to get a list from a api which columns should be shown on my material react table, but there are always no columns. I see that the state is updated but it seems like the table is not refreshing as soon as the state contains the list. So initally i got the full list but some of those colums are not active and should be fetched from an api, so i filter the list. What am I missing?

// imports here

export default function ServiceList() {
  const [activatedFields, setActivatedFields] = useState([]);

  async function getServices() {
    const activatedFieldsQuery = await axios.get(
      `${process.env.REACT_APP_BACKEND}/settings/editServices`
    );
    setActivatedFields(activatedFieldsQuery.data["0"].value.activatedFields);
  }

  let allColumns = [
    {
      accessorKey: "_id",
      header: "_id",
    },
    {
      accessorKey: "werk_standort",
      header: "werk_standort",
    },
    {
      accessorKey: "fachbereich",
      header: "fachbereich",
    },
    // removed most for better visibility
  ];

  const columns = useMemo(
    () =>
      allColumns.filter(function (el) {
        return activatedFields.includes(el.accessorKey);
      }),
    []
  );

  let table = useMaterialReactTable({
    columns,
    data: services, //fetched from other api call
  });

  useEffect(() => {
    getServices();
  }, []);

  return (
    <>
      <MaterialReactTable table={table} />
    </>
  );
}

Upvotes: 0

Views: 181

Answers (1)

Petros
Petros

Reputation: 1617

You're using useMemo to filter the allColumns array based on the activatedFields state. However, you've provided an empty array [] as the dependency array.

This means that the useMemo hook will only calculate the columns value once, when the component is first rendered. At this point, activatedFields is an empty array, so the columns array will also be empty

Modify your columns const to this:

const columns = useMemo(
  () =>
    allColumns.filter(function (el) {
      return activatedFields.includes(el.accessorKey);
    }),
  [activatedFields] // include activatedFields in the dependency array
);

Also, make sure that the useMaterialReactTable is implemented in a way that handles the changes to its columns. If not then the table variable might need to get re-calculated

Upvotes: 0

Related Questions