Rohan Agarwal
Rohan Agarwal

Reputation: 2609

Prevent image from rerendering at every state change - React

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.

Upvotes: 13

Views: 15413

Answers (1)

HMR
HMR

Reputation: 39250

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>

Upvotes: 14

Related Questions