mirror of
https://github.com/zoriya/react-native-web.git
synced 2026-08-15 18:45:06 +00:00
[fix] Image: image LOADED state is only captured initially
If the Image component is rendered with a `null` source, and consecutively updated with actual source url that was already loaded, it would fail to pick up the change - `state` would be `IDLE` for a brief moment and this would cause a small flicker when the image renders Let's always start from IDLE state, and update `shouldDisplaySource` condition to be based on `ImageLoader.has` cache or not Fix #2492
This commit is contained in:
committed by
Nicolas Gallagher
parent
e722282c09
commit
7cb5800e25
+17
-17
@@ -255,23 +255,6 @@ exports[`components/Image prop "source" is correctly updated when missing in ini
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/Image prop "source" is not set immediately if the image has not already been loaded 1`] = `
|
||||
<div
|
||||
class="css-view-175oi2r r-flexBasis-1mlwlqe r-overflow-1udh08x r-zIndex-417010"
|
||||
>
|
||||
<div
|
||||
class="css-view-175oi2r r-backgroundColor-1niwhzg r-backgroundPosition-vvn4in r-backgroundRepeat-u6sd8q r-bottom-1p0dtai r-height-1pi2tsx r-left-1d2f490 r-position-u8s1d r-right-zchlnj r-top-ipm5af r-width-13qz1uu r-zIndex-1wyyakw r-backgroundSize-4gszlv"
|
||||
style="background-image: url(https://google.com/favicon.ico);"
|
||||
/>
|
||||
<img
|
||||
alt=""
|
||||
class="css-accessibilityImage-9pa8cd"
|
||||
draggable="false"
|
||||
src="https://google.com/favicon.ico"
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/Image prop "source" is set immediately if the image has already been loaded 1`] = `
|
||||
<div
|
||||
class="css-view-175oi2r r-flexBasis-1mlwlqe r-overflow-1udh08x r-zIndex-417010"
|
||||
@@ -323,6 +306,23 @@ exports[`components/Image prop "source" is set immediately if the image was prel
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/Image prop "source" is set immediately while image is loading and there is no default source 1`] = `
|
||||
<div
|
||||
class="css-view-175oi2r r-flexBasis-1mlwlqe r-overflow-1udh08x r-zIndex-417010"
|
||||
>
|
||||
<div
|
||||
class="css-view-175oi2r r-backgroundColor-1niwhzg r-backgroundPosition-vvn4in r-backgroundRepeat-u6sd8q r-bottom-1p0dtai r-height-1pi2tsx r-left-1d2f490 r-position-u8s1d r-right-zchlnj r-top-ipm5af r-width-13qz1uu r-zIndex-1wyyakw r-backgroundSize-4gszlv"
|
||||
style="background-image: url(https://google.com/not-yet-loaded-image.ico);"
|
||||
/>
|
||||
<img
|
||||
alt=""
|
||||
class="css-accessibilityImage-9pa8cd"
|
||||
draggable="false"
|
||||
src="https://google.com/not-yet-loaded-image.ico"
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/Image prop "style" removes other unsupported View styles 1`] = `
|
||||
<div
|
||||
class="css-view-175oi2r r-flexBasis-1mlwlqe r-overflow-1udh08x r-zIndex-417010"
|
||||
|
||||
@@ -277,8 +277,8 @@ describe('components/Image', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('is not set immediately if the image has not already been loaded', () => {
|
||||
const uri = 'https://google.com/favicon.ico';
|
||||
test('is set immediately while image is loading and there is no default source', () => {
|
||||
const uri = 'https://google.com/not-yet-loaded-image.ico';
|
||||
const source = { uri };
|
||||
const { container } = render(<Image source={source} />);
|
||||
expect(container.firstChild).toMatchSnapshot();
|
||||
|
||||
+6
-13
@@ -225,24 +225,18 @@ const BaseImage: ImageComponent = React.forwardRef((props, ref) => {
|
||||
}
|
||||
}
|
||||
|
||||
const [state, updateState] = React.useState(() => {
|
||||
const uri = resolveAssetUri(source);
|
||||
if (uri != null) {
|
||||
const isLoaded = ImageLoader.has(uri);
|
||||
if (isLoaded) {
|
||||
return LOADED;
|
||||
}
|
||||
}
|
||||
return IDLE;
|
||||
});
|
||||
|
||||
const [state, updateState] = React.useState(IDLE);
|
||||
const [layout, updateLayout] = React.useState({});
|
||||
const hasTextAncestor = React.useContext(TextAncestorContext);
|
||||
const hiddenImageRef = React.useRef(null);
|
||||
const filterRef = React.useRef(_filterId++);
|
||||
const requestRef = React.useRef(null);
|
||||
const uri = resolveAssetUri(source);
|
||||
const isCached = uri != null && ImageLoader.has(uri);
|
||||
const shouldDisplaySource =
|
||||
state === LOADED || (state === LOADING && defaultSource == null);
|
||||
state === LOADED ||
|
||||
isCached ||
|
||||
(state === LOADING && defaultSource == null);
|
||||
const [flatStyle, _resizeMode, filter, _tintColor] = getFlatStyle(
|
||||
style,
|
||||
blurRadius,
|
||||
@@ -297,7 +291,6 @@ const BaseImage: ImageComponent = React.forwardRef((props, ref) => {
|
||||
}
|
||||
|
||||
// Image loading
|
||||
const uri = resolveAssetUri(source);
|
||||
React.useEffect(() => {
|
||||
abortPendingRequest();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user