Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to dynamically render list of components without re-rendering entire list with every new addition?

Tags:

I want to render a list of components that have a 1:1 relationship with some objects in my redux store.

My current code is:

  props.images.forEach(imageFile => {
    let objectURL = URL.createObjectURL(imageFile);

    const newStyles = { 
      left: `${leftPosition}%`,
      top: `${topPosition}%`
    }

    previewFloats.push(
      <div className="Preview" style={{...style, ...newStyles}} key={v4()}></div>
    )
  });

  return(
    previewFloats
  )

Edit: Example here (codesandbox.io/s/brave-mcnulty-0rrjz)

The problem being that performance takes a pretty big hit rendering an entire list of background images as the list grows.

What is a better way to achieve this?

Edit: still unsure why background-image src is triggering a re-render, but the suggestion to use an <img> element instead has things working as intended.

like image 520
colemars Avatar asked Jul 23 '19 12:07

colemars


People also ask

How do you avoid full component re-renders?

1. Memoization using useMemo() and UseCallback() Hooks. Memoization enables your code to re-render components only if there's a change in the props. With this technique, developers can avoid unnecessary renderings and reduce the computational load in applications.

How do you render a list dynamically in React?

To render a list dynamically in React, we start by adding a property to the state object. We can populate that property with an array of strings like so. Great. Now we want to move to the render() method to render each list item dynamically.

How do you stop a component from rendering even after state has been updated?

To prevent the render method from being called, set the return to false, which cancels the render. This method gets called before the component gets rendered. Sometimes you may want to prevent re-render even if a component's state or prop has changed.

How do you render a component dynamically?

The dynamic render function is the renderPropertyEditor function. It uses the activeData variable to determine which component to render. const PropertyEditor = Config[activeData. type]; return (<PropertyEditor codeData={activeData} updateData={onUpdateCodeData} />);


2 Answers

Array.map() allows dynamic rendering of elements in React, so that only those who change their props will re-render (as explained in the documentation).

If you'll use this method - rather than create the full array and render it fully - React will only re-render elements that are supposed to be updated:

props.images.map((imageFile, index) => {
    let objectURL = URL.createObjectURL(imageFile);

    const newStyles = { 
      left: `${leftPosition}%`,
      top: `${topPosition}%`
    }

    return (
      <div className="Preview" style={{...style, ...newStyles}} key={index}></div>
    )
});

Note that I've modified the key property of each element in the array. It should be unique and I didn't know what v4() is, so I just used the array indices.
React's documentation actually explains really well about these:

Keys help React identify which items have changed, are added, or are removed

like image 62
GalAbra Avatar answered Oct 03 '22 22:10

GalAbra


Your answer is with 'key' property of react components. It's built for such cases Assuming this is render part of your component, you should have something like this:

return this.props.images.map(imageFile => (
    <div className="Preview" key={imageFile}></div>
))

Assuming imageFile is a unique string. This way react will rerender your virtual dom but it'll recognise that there is no need to dom update for same elements with same key property

like image 20
Doğancan Arabacı Avatar answered Oct 03 '22 22:10

Doğancan Arabacı