In my component I have used an image in the following manner:
<div className="margin-10 flex-row-center">
<span>
<img src={spinner} className="spinner" />
</span>
<span className="padding-10">
We are checking your details
</span>
</div>
This is a few lines from a big functional component that has many states in it. This component is also sometimes used as a child to other components.
Now, whenever a state gets updated, a re-render of the component happens. Natural.
However, a visual update on the image is visible, which is not a good UX.
Any help, on how to prevent such unnecessary re-rendering of images. Also, if there is any other way to use images in React, that could solve this problem, will be helpful.
There is no way to prevent a component that uses a portion of Context value from re-rendering, even if the used piece of data hasn't changed, even with useMemo hook. Context selectors, however, could be faked with the use of higher-order components and React. memo .
To get rid of your infinite loop, simply use an empty dependency array like so: const [count, setCount] = useState(0); //only update the value of 'count' when component is first mounted useEffect(() => { setCount((count) => count + 1); }, []); This will tell React to run useEffect on the first render.
React components automatically re-render whenever there is a change in their state or props. A simple update of the state, from anywhere in the code, causes all the User Interface (UI) elements to be re-rendered automatically.
You can try to make image it's own pure component:
const Image = React.memo(function Image({ src }) {
return <img src={src} className="spinner" />;
});
And then use it:
<div className="margin-10 flex-row-center">
<span>
<Image src={spinner} />
</span>
<span className="padding-10">
We are checking your details
</span>
</div>
Here is a working snippet:
const Image = React.memo(function Image({ src }) {
return <img src={src} className="spinner" />;
});
function App() {
const [counter, setCounter] = React.useState(0);
const src =
'https://en.bcdn.biz/Images/2018/6/12/f0d2c2ca-dc61-4613-9685-6c98cbb8a990.jpg';
React.useEffect(() => {
const t = setInterval(() => {
setCounter((c) => c + 1);
}, 100);
});
return (
<div>
<div>{counter}</div>
<div>
<Image src={src} />
</div>
</div>
);
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
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