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.
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.
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.
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.
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} />);
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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With