I have table component with tableRows stored in useState.
Also I have searcher component outside of table component.
When data inside of searcher changes, tableRows updates inside useEffect.
And it works good, but it causes two rerender. And i understand why. First rerender because of useSelector, and the second because useEffect have useSelector value as dependency.
But how to avoid one rerender. I want it to rerenders when tableRows changes, but not when searcher changes.
const CatalogTable: React.FC<CatalogTableProps> = ({rows}) => {
const [tableRows, setTableRows] = React.useState(rows)
const searcher = useSelector(getTableSearcher, shallowEqual)
const getData = async () => {
const {data} = await CatalogService.getAllCatalogProducts({page: 1, searcher: searcher})
setTableRows(data.products)
}
React.useEffect(() => {
if(searcher)
getData()
}, [searcher])
return (
<>
<div className={styles.defaultTable}>
<Table
headers={headers}
label="Products catalog"
rows={tableRows}
total={total}
pagination
addButton
editButtons
searcher
getPage={(page: number) => nextPage(page)}
type='catalog'
/>
</div>
</>
)
}
export default CatalogTable
One of the possible solutions is memoization:
const CatalogTable: React.FC<CatalogTableProps> = ({rows}) => {
const [tableRows, setTableRows] = React.useState(rows)
const searcher = useSelector(getTableSearcher, shallowEqual)
const getData = async () => {
const {data} = await CatalogService.getAllCatalogProducts({page: 1, searcher: searcher})
setTableRows(data.products)
}
React.useEffect(() => {
if(searcher)
getData()
}, [searcher])
const result = useMemo( () =>
<>
<div className={styles.defaultTable}>
<Table
headers={headers}
label="Products catalog"
rows={tableRows}
total={total}
pagination
addButton
editButtons
searcher
getPage={(page: number) => nextPage(page)}
type='catalog'
/>
</div>
</>, [tableRows]
);
return result;
}
export default CatalogTable
another solution is putting both tableRows and search query inside redux store and update them simultaneously through async middleware.