How to memoize a part of a component list in React

Viewed 2173

Looking for some React rendering/useMemo guidance.

I have a list of 2,000+ items, each of which is a React component. There is a highlight of a "currently selected" item that renders independently of the list. That allows me to render the list only once.

useMemo(_ => {
  <Item .../>
  <Item .../>
  ...
  <Item .../>
}, [contents])

Now I'm adding the ability to "expand" a list item in it, which only adds new DOM elements without modifying the list item in its non-expanded state.

You can imagine each Item being two parts:

function Item(props) {
  return
    <div>
      <SubItem />
      {
        if (props.open) {
          <OtherItem />
        } else {
          null
        }
      }
    </div>
}
useMemo(_ => {
  <Item open={1 == current} .../>
  <Item open={2 == current} .../>
  ...
  <Item open={n == current} .../>
}, [contents, current])

Question: Is there a way to support this without having to re-render the whole list every time I expand/collapse a new item?

Unfortunately the expanded DOM elements are "in flow", so the expansion pushes list items after it (not just a hover/overlay thing).

1 Answers

I think you can do it this way:

const Item = useMemo( props => {
    return (
        //...your JSX code here.
    )
}, []);

[...2000].map(props => <Item {...props}>);
Related