I have an application that makes requests for an API and has thousands of results. The API works with limit offset type pagination. That is, I pass as a parameter the limit (how many records I want to bring) and the offset (from which record I want to bring).
The problem is that the database has thousands of results per day. About 150k of results. That is, whenever I update the state of React to add the new results, I'm having a performance problem, because React renders all the data all over again.
Below is part of the code.
async getHits(filters, resetContent = false) {
if(resetContent) {
this.setState({
isLoading: true
})
}
try {
const { data: { result } } = await API_CONFIG.get(`/hit${filters}`);
const formattedHits = formatHits(result);
let current;
if(resetContent) {
current = [...formattedHits];
} else {
current = [...this.state.hits, ...formattedHits]
}
this.setState(prevState => ({
hits: current,
currentOffset: resetContent ? 1 + DEFAULT_PAGINATION : prevState.currentOffset + DEFAULT_PAGINATION
}));
} catch (e) {
this.setState({
hits: [],
error: 'Houve um erro durante a requisição. Por favor, recarregue e tente novamente.'
});
} finally {
this.setState({
isLoading: false,
isLoadMoreLoading: false
})
}
}
For example, when I click to load more, I change the state to set 'isLoadMoreLoading' to true, so I change the text from Carregar mais (Load more in portuguese) to Carregando (Loading in portuguese). This procedure takes a long time, as React is updating the entire state again.
Here I render the content:
const areEqual = (nextProps, prevProps) => {
if(nextProps === prevProps) {
return true
};
return false;
};
const TableResults = props => {
const { hits, isLoading, error } = props;
return (
<Table>
<thead>
<tr>
<TableHeader>Data</TableHeader>
<TableHeader>Parceiro</TableHeader>
<TableHeader>ID Arquivo</TableHeader>
<TableHeader>Nome do Cliente</TableHeader>
<TableHeader>Regra Afetada</TableHeader>
<TableHeader>Valor ME</TableHeader>
<TableHeader>Merchant Final</TableHeader>
<TableHeader>País Merchant Final</TableHeader>
<TableHeader>Gerador do Hit</TableHeader>
</tr>
</thead>
<tbody>
{isLoading && (
<tr>
<td className="content-not-allowed" colSpan={9}>
<Loader />
</td>
</tr>
)}
{!isLoading && error && (
<tr>
<td className="content-not-allowed not-found" colSpan={9}>
<span>{error}</span>
</td>
</tr>
)}
{!isLoading && !hits.length && !error && (
<tr>
<td className="content-not-allowed not-found" colSpan={9}>
<span>Sem resultados, revise sua busca.</span>
</td>
</tr>
)}
{!isLoading && !!hits.length && !error && (
hits.map(hit => (
<tr onClick={e => {
e.preventDefault();
props.history.push('/compliance/operations/'+hit.hit_id)
}} key={hit.hit_id}>
<td>{hit.created_at || '-'}</td>
<td>{hit.partner || '-'}</td>
<td>{hit.file_id || '-'}</td>
<td>{hit.cliente_nome || '-'}</td>
<td>{renderHitGenerator(hit.compliance_integration).description}</td>
<td>{hit.valorme || '-'}</td>
<td>{hit.merchant_nome_final || '-'}</td>
<td>{hit.merchant_pais_final || '-'}</td>
<td>{renderHitGenerator(hit.compliance_integration).name}</td>
</tr>
))
)}
</tbody>
</Table>
)
}
export default withRouter(React.memo(TableResults, areEqual));
I looked on the internet to optimize the results for this amount of data, but I didn't find anything satisfactory.
How can I update the state of React with this amount of data and still be a performer.
Thanks.