I am working on a fix for a Material Table in a Next.js application, and I want to be able to retain search results of even after i visit another page, I have tried using local state to store the search results but every time i visit the page the table re-renders and the data is refetched. What is the best approach here? This is the component:
<MaterialTable
tableRef={tableRef}
title={
<Text variant="hSmSemiBold" mt="20px">
Customers
</Text>
}
columns={[
{
title: <h6>Account Type</h6>,
field: 'institution',
cellStyle: {
maxWidth: '121px'
},
render: ({ institution }) => {
return institution ? (
<span className="text-warning">Institution</span>
) : (
<span className="text-success">Individual</span>
);
}
},
{
title: <h6>Name</h6>,
field: 'fullName',
cellStyle: {
maxWidth: '165px',
textTransform: 'capitalize'
},
render: ({ institution, institutionName, fullName }: { [x: string]: any }) => {
return institution ? institutionName : fullName;
}
},
{
title: <h6>Aggregate Holdings</h6>,
field: 'userUuid',
cellStyle: {
maxWidth: '134px'
},
render: ({ userUuid }) => {
return `${aggregatedCurrencies[userUuid]?.symbol || '$'} ${formatAmount(
(anh ?? {})[userUuid || '']
)}`;
}
},
{
title: <h6>Personal Info</h6>,
field: 'customerProgress',
cellStyle: {
maxWidth: '146px'
},
render: ({
customerProgress: {
customerCreated: { state }
}
}) => <CustomerStatus customerState={state} stage="customerCreated" />
},
{
title: <h6>KYC status</h6>,
field: 'customerProgress',
cellStyle: {
maxWidth: '135px'
},
render: ({
customerProgress: {
kyc: { state }
}
}) => <CustomerStatus customerState={state} stage="kyc" />
},
{
title: <h6>AML</h6>,
field: 'customerProgress',
cellStyle: {
maxWidth: '110px'
},
render: ({
customerProgress: {
aml: { state }
}
}) => <CustomerStatus customerState={state} stage="accreditation" />
},
{
title: <h6>Accreditation</h6>,
field: 'customerProgress',
cellStyle: {
maxWidth: '151px'
},
render: ({
customerProgress: {
accreditation: { state }
}
}) => <CustomerStatus customerState={state} stage="accreditation" />
},
{
title: <h6>Assignee</h6>,
field: 'assignedAgent',
render: ({ assignedAgent, userUuid }) => (
<Assignee
key={userUuid}
assignedAgent={
customerAgents[userUuid as keyof typeof customerAgents]
? customerAgents[userUuid as keyof typeof customerAgents]
: assignedAgent
}
userUuid={userUuid}
/>
),
cellStyle: {
padding: 0,
maxWidth: '163px'
}
},
{
title: <h6>Source</h6>,
field: 'objectCreatedBy',
cellStyle: {
maxWidth: '106px'
}
},
{
title: <h6>Action</h6>,
field: 'userUuid',
cellStyle: {
maxWidth: '333px'
},
sorting: false,
render: ({ userUuid, email, firstName, customerCreated }) => {
const query = customerCreated ? { id: userUuid } : { name: firstName, email };
return (
<Flex>
<Link
href={{ pathname: customerCreated ? 'customer' : 'create-customer', query }}
className="text-danger"
>
<Button size="xs">{customerCreated ? 'View' : 'Update Customer'}</Button>
</Link>
<CopyEmail size="xs" ml="10px" email={email} />
</Flex>
);
}
}
]}
data={(query) => {
const { pageSize, page, search, orderBy, orderDirection } = query;
const url = `${endpoints.customers}?per_page=${pageSize === 5 ? 10 : pageSize}&page=${
page + 1
}&direction=${orderDirection}&search=${search.replace('+', '%2B')}&order_by=${
orderBy?.field || ''
}`;
return new Promise((resolve) => {
apiCall(METHOD_GET, activeFilter ? url + filterUrl : url, {}, {})
.then(({ data, page, totalCount }) => {
resolve({
data: data,
page: page - 1,
totalCount: totalCount
});
})
.catch(() => {
resolve({
data: [],
page: 0,
totalCount: 0
});
});
});
}}
style={{
boxShadow: 'drop-shadow(0px 2px 4px rgba(0, 0, 0, 0.1))',
backgroundColor: `${colors.defaultWhite}`,
borderRadius: '8px'
}}
options={{
thirdSortClick: false,
search: true,
pageSizeOptions: [10, 20, 50, 100],
pageSize: 10,
initialPage: 0,
headerStyle: {
color: `${colors.deepBlue}`,
fontSize: '14px',
fontWeight: 600
},
searchFieldStyle: {
padding: '6px 12px',
border: `1px solid ${colors.concrete}`,
borderRadius: '4px'
},
rowStyle: {}
}}
/>
I have tried to store the searchQuery results in local state and then add the data the data prop above but getting an error no overload matches this call.
I was able to get the searchQuery and store the state of the data table but the search field is not able to maintain the state since the results of the lists are already paginated from the endpoints that return the data.
Also Material Table library forces a re-render every time the page is visited which re-fetches the data since we are using a custom query function on the same.