0

I have a component which has <img src.../> as one of the children. When I watch the network tab, the source of the image is being pulled twice on each re-render of the parent component. I have 2 questions:

  1. why does image loads twice, and
  2. how do I stop a component that contains <img> tag from re-rendering. Every time something happens in the parent component, the network tab shows the image being pulled twice, while I don't need it be re-pulled at all

I have tried creating a separate component which all that it has is <img> tag. I tried it as a function and a Class and as a memoized function:

const MyImage = React.memo(props => {
    console.log('render image')// logged once per render, but source pulled twice
    return <img alt="" src={props.src} onLoad={props.onLoad}/>
})

and like this:

class MyImage extends React.Component {
    shouldComponentUpdate(nextProps, nextState, nextContext) {
        console.log(nextProps, this.props)// never logged
        return nextProps.src === this.props.src;
    }

    render() {
        console.log('render img')//logged once per render, but source pulled twice
        return <img alt="" src={this.props.src} onLoad={this.props.onLoad}/>
    }
}

and like this:

function MyImage(props) {
    const {src, onLoad} = props;
    const [source, setSource] = useState(src);

    useEffect(() => {
        console.log('use effect')
        setSource(src);
    }, []); // React Hook useEffect has a missing dependency: 'src'. But shouldn't it be empty for initial loads?

    return <img alt="" src={source} onLoad={onLoad}/>
}

It seems like the onLoad event might be causing the source to be pulled twice (if I remove it, the network tab shows only one request). But why? All that the onLoad is doing is setting classes that are used by parent component

chibis
  • 658
  • 2
  • 12
  • 22
  • why still use useState and useEffect when you can just directly put the prop.src value in the src propert of img. ex `` – Semi-Friends Apr 29 '22 at 20:33
  • I tried that too. I used the hooks in hopes I can somehow prevent re-rendering there by checking if the source has changed – chibis Apr 29 '22 at 20:41
  • 2
    use the theone with React.memo and make sure you wrap onLoad in useCallback from your parent component and see if it still rerenders. also make sure that you only render Image when src is not empty. – Semi-Friends Apr 29 '22 at 20:52
  • Check [Why is my React component is rendering twice?](https://stackoverflow.com/questions/48846289/why-is-my-react-component-is-rendering-twice) out – F_V Apr 29 '22 at 21:06
  • thanks for pointing this out. I've seen that before and I have commented out the Strict Mode for this exact reason – chibis Apr 29 '22 at 21:10
  • I believe there is more going on here in the parent component. I took your functional component and did some testing and the image only loaded once. Note that I did include `src` in the dependency list for the useEffect. If there's concern that `src` might be null, you can do a test such as `if ( src ) { setSource(src); }`. I've learned not to argue with React over the dependency list. Anyway, so the component in general seems fine, making me think that your parent component is re-rendering and causing the double load – Mike Willis Apr 29 '22 at 21:26
  • that is possible too, in fact there is a lot that is going on in the parent that causes it to legitimately re-render and that is my question #2, how do I stop re-rendering a child when parent re-renders. I don't need to re-pull the image when some text changes. Is it possible? – chibis Apr 29 '22 at 22:42
  • @Semi-Friends, thanks a lot!!! I had to wrap onLoad functions all the way up to the first parent that sends it (a couple levels up) and created `MyImage` component with `React.memo` and it does not re-render anymore with each parent re-render – chibis Apr 30 '22 at 03:47

0 Answers0