react-native-fast-image
react-native-fast-image copied to clipboard
Stateful changes in "resizeMode" prop on Android do not affect the image
Describe the bug When you change the resizeMode prop depending on the state, like in the example below, the image does not change to the new resizeMode on Android. It works fine on iOS.
To Reproduce Here's a small example:
const App: React.FC = () => {
const [resizeMode, setResizeMode] = useState(FastImage.resizeMode.contain);
return (
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<FastImage
style={{width: 300, height: 700, backgroundColor: 'blue'}}
source={{
uri:
'https://bloximages.newyork1.vip.townnews.com/chronicleonline.com/content/tncms/assets/v3/editorial/8/10/8104fdd4-c181-11ea-85cc-7721a478bede/5f066f66c0e74.image.jpg',
}}
resizeMode={resizeMode}
/>
<TouchableOpacity
onPress={() =>
setResizeMode(
resizeMode == FastImage.resizeMode.stretch
? FastImage.resizeMode.contain
: FastImage.resizeMode.stretch,
)
}>
<Text>Current mode: {resizeMode}</Text>
</TouchableOpacity>
</View>
);
};
Expected behavior I expected the image to change to the current resizeMode prop given, as it does in the default react-native Image component.
Screenshots N/A
Dependency versions
- React Native version: 0.63.4
- React version: 16.31.1
- React Native Fast Image version: 8.3.4
hi @oakleyaidan21 , any alternative you got for this?
@Dhanraj-Naik sadly no, I ended up just using the regular react native Image instead for images I needed to resize on the fly.
Hello,
I encountered the same issue on Android with the following code:
const resizeMode = useMemo(() => {
return isInLandscapeMode ? FastImage.resizeMode.cover : FastImage.resizeMode.contain
}, [isInLandscapeMode])
return (
<Image
height={theme.device.screenWidth * ratio}
resizeMode={resizeMode}
src={src}
style={{
width: '100%',
height: '100%',
}}
width={theme.device.screenWidth}
/>
I ended up using the same workaround as @oakleyaidan21 (using native image).
Hi there!
I've encountered this bug too. I found a simple solution you can use to make RNFI pick up your resizeMode
property.
It seems that the library doesn't re-apply the resizeMode
property after values change.
I've used a build in React Native Image.getSize
property to calculate the aspect ratio for the image during the render in the useEffect
hook. First, we will receive width & height and based on these values, and we can calculate the ratio. As soon as we get the ratio, you can render the RNFI component with the ternary resizeMode property.
It might not work for all cases, but it will work if you load the network images.
Here is a snippet:
import { Image } from 'react-native'
// your component
const [aspectRatio, setAspectRatio] = useState(null)
useEffect(() => {
Image.getSize(uri,
(width, height) => {
setAspectRatio(width / height)
},
error => {
console.error(`Couldn't get the image size: ${error.message}`)
}
)
}, [])
const resizeMode = isHorizontal ? 'cover' : 'contain'
const aspectRatioCalculated = aspectRatio !== null
return (
{aspectRatioCalculated && (
<FastImage
...
resizeMode={resizeMode}
/>
)}
)
Since a change of resizeMode
doesn't have any effect on Android one (blunt) solution is to trigger re-render of the component. This can be achieved by simply changing the key of a component.
Simple example:
const MyImage = () => {
const resizeMode = someBoolean ? 'cover' : 'contain'
const additionalProps = Platform.OS === 'android' ? { key: resizeMode } : {}
return (
<FastImage
...
{...additionalProps}
resizeMode={resizeMode}
/>
)
}