I would like to know it’s necessary to use useMemo in react table for columns and data if yes why it’s so?
This is my code:
import React, { useMemo } from "react";
import useData from "../../hooks/useData";
import Table from "./Table";
import Loader from "../../assets/imgs/loader.svg";
const TableSection = React.memo(({ query, isOpen }) => {
const { data, runtime, error } = useData(query);
const column =
data.length > 0 &&
Object.keys(data[0]).map((key) => {
const result = data[0][key]
.replace(/([A-Z]+)/g, " $1")
.replace(/([A-Z][a-z])/g, " $1");
return {
Header: result,
accessor: key,
};
});
const columns = useMemo(() => column, [column]);
const queryData = useMemo(() => data.slice(1), [data]);
if (error)
return (
<section
className={`${
isOpen ? "col-start-2" : "col-start-1"
} col-end-3 row-start-3 row-end-4 text-white m-6`}
>
<h1 className="text-center font-bold text-xl text-primary-dark">
Something Went Wrong{" "}
<span role="img" aria-label="sad face">
😔
</span>
</h1>
</section>
);
return (
<>
<section
className={`${
isOpen ? "col-start-2" : "col-start-1"
} col-end-3 row-start-3 row-end-4 text-white mx-6 my-12 lg:mx-12 overflow-hidden`}
>
{data.length > 0 ? (
<>
<p className="text-primary-dark">
Query took:{" "}
<span className="font-bold">{`${runtime.toFixed(2)} ms`}</span>
</p>
<Table
columns={columns}
completeData={data}
data={queryData}
query={query}
/>
</>
) : (
<img src={Loader} className="w-20 mx-auto" alt="loader" />
)}
</section>
</>
);
});
export default TableSection;
>Solution :
Yes, it is recommended to use useMemo.
The useTable hook takes the columns and if your component re-renders for whatever reason, a new columns array will be created (if useMemo isn’t used) and useTable will recalculate the underlying logic unnecessarily.
btw, you’re using useMemo incorrectly as column is defined outside (changes on rerendering) and is added as a dependency. This is how you should use it
const columns = useMemo(() => {
if (!data[0].length) return [];
return Object.keys(data[0]).map((key) => {
const result = data[0][key]
.replace(/([A-Z]+)/g, ' $1')
.replace(/([A-Z][a-z])/g, ' $1');
return {
Header: result,
accessor: key,
};
});
}, [data]);