简体   繁体   中英

How to conditionally update react list components

I have the React app below ( jsfiddle ):

const ListItem = (props) => {
    return (
        <div className={props.active ? "active" : ""}>Item {props.index}</div>
  )
}

const initialItems = ["item1", "item2", "item3", "item4", "item5"]

const App = (props) => {
    const [activeIndex, setActiveIndex] = React.useState(0);

  const goUp = () => {
    if(activeIndex <= 0) return;

    setActiveIndex(activeIndex - 1);
  }

  const goDown = () => {
    if(activeIndex >= initialItems.length - 1) return;

    setActiveIndex(activeIndex + 1);
  }

    return (
    <div>
      <p>
        <button onClick={goUp}>Up</button>
        <button onClick={goDown}>Down</button>
      </p>
      <div>
        {initialItems.map((item, index) => (
            <ListItem active={index === activeIndex} index={index} key={index} />
        ))}
      </div>
    </div>
  )
}

ReactDOM.render(
  <App />,
  document.getElementById('container')
);

Using buttons you can highlight the current list element. The issue with the current approach is that on every active index change it re-renders the full list. In my case, the list might be very big (hundreds of items) with a more complicated layout, which introduces performance problems.

How might this code be modified so it updates only specific list item components and doesn't trigger re-render of all others? I'm looking for a solution without third-party libraries and without direct DOM manipulations.

You can wrap ListItem with React.memo() as here .

This is your ListItem component,

const ListItem = (props) => {
    return (
        <div className={props.active ? "active" : ""}>Item {props.index}</div>
  )
};

By using React.Memo(),

const ListItem = React.memo((props) => {
    return (
        <div className={props.active ? "active" : ""}>Item {props.index}</div>
  )
});

In this case ListItem is only rendered when props gets changed.

See for updated JsFiddle and check with console.log() s.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM