reactjs - Avoid re-rendering a big list of items with react-redux -


i using redux react , typescript application. working many items used @ different places of app. state looks this:

{     items: {42: {}, 53: {}, ... }, //a large dictionary of items     itempage1: {         itemsid: [ 42, 34, 4 ],         ...     },     itempage2: { ...      },     ... } 

the user can modify attributes of items dispatching actions. when happen need redraw components have been modified in each pages. issue items quite big , cant afford redraw of them @ each small modification. wondering approach work:

  • i have fist component <itempage1> connects store of states stored in tree under itempage1 e.g. list of items id: itemsid.
  • inside <itempage1>, loop on itemsid property generate multiple filteritem components: itemsid.map( itemid => return <filteritem id=itemid>);
  • finally each item connected using ownprops correct part of state:

    const mapstatetoitemprops = (state, ownprops) => {     return {         item: state.items[ownprops.id],     } } const mapdispatchtoitemprops = (dispatch, ownprops) => {     return null; } const filteritem = connect(     mapstatetoitemprops,     mapdispatchtoitemprops )(item) 

can confirm or refute if update item of id 42, item going re-rendered ?

when rendering big list need take considerations few things :

  • lower total number of dom elements need render (by not rendering items not visible on screen, known virtualization)
  • don't re-render items have not changed

basically, want avoid complete re-render of list (or page) when user edits 1 single row. can achieved how did it, i.e : passing list container ids of items need rendered, , map on these ids connect each component using ownprops. if have dump <item/> component, <itempage/> component create connected connect(<item/>) component.

this going work, if put console.log('item rendered') in <item/> component class notice there 1 call.

but (and it's big but), not obvious when working react-redux connected components depends on ownprops always rerender if any part of state change. in case, if <item/> components not re-render, wrapped component connect(item) ! if have few dozens of items, might encounter latency if actions need dispatched (for example when typing in input). how avoid ? use factory function use ownprops initial props :

const mapstatetoitemprops = (_, initialprops) => (state) => {     return {         item: state.items[initialprops.id],  // we're not relying on second parameters "ownprops" here, wrapper component not rerender     } } const mapdispatchtoitemprops = (dispatch, ownprops) => {     return null; } const filteritem = connect(     mapstatetoitemprops,     mapdispatchtoitemprops )(item) 

i suggest take this other answer.

you might interested in these excellent slides : big list high performance react & redux

and finally, should definitively take react-virtualized perform virtualization of list (i.e, displaying item user can see).


Comments