I have a react component that is the detail view from a list.
I am trying to replace the image with a default image if the image does not exist and there is a 404 er
Here's an answer using hooks:
import React, { useState } from 'react'
/**
* Returns an object that can
* be spread onto an img tag
* @param {String} img
* @param {String} fallback
* @returns {Object} { src: String, onError: Func }
*/
function useFallbackImg(img, fallback) {
const [src, setImg] = useState(img)
function onError(e) {
console.log('Missing img', img, e)
// React bails out of hook renders if the state
// is the same as the previous state, otherwise
// fallback erroring out would cause an infinite loop
setImg(fallback)
}
return { src, onError }
}
/**
* Usage
*/
function Image({src, fallback, ...rest}) {
const imgProps = useFallbackImg(src, fallback)
return
}
And if you are want to handle the src
prop changing, you can pass a key
prop of the src
.
https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key
The only extreme contrived edge case where using a key like this might fail is with sibling components. I think only one sibling node will render if they have the same key. To get around this you could probably wrap the Image in a <>
Fragment
.
<> >
<> >