[英]React custom Image Component doesn't render based on given condition
I am trying to build an image component in ReactJS with a fallback
prop if provided will render the fallback component until the image has been downloaded and rendered properly.我正在尝试在 ReactJS 中构建一个带有fallback
道具的图像组件,如果提供了将呈现后备组件,直到图像被下载并正确呈现。
The conditional rendering is as follows:条件渲染如下:
if (loading) {
return fallback;
} else if (error) {
return <span>ERROR</span>;
} else if (src) {
return (
<>
<img alt="" ref={imageRef} decoding="async" src={props.src} />
</>
);
} else return null;
}
And the Image is called in the App.js file as并且图像在 App.js 文件中被称为
<Image
src="https://source.unsplash.com/random/100x100"
fallback={<h1>Loading...</h1>}
/>
I'm using useEffect
hook to call function that further checks if the image has been mounted to the screen using ref
.我正在使用useEffect
挂钩调用 function 进一步检查图像是否已使用ref
安装到屏幕上。
React.useLayoutEffect(() => {
imageRef.current = true;
start();
return () => {
imageRef.current = false;
};
}, []);
async function start() {
if (!src || !fallback) {
const errorMessage = "`src` & `fallback` must be provided";
setError(errorMessage);
return;
}
setLoading(true);
tryLoadImage();
}
async function loadImage() {
const img = imageRef.current;
if (!img) {
return;
}
setLoading(false);
}
async function tryLoadImage() {
try {
await loadImage();
if (imageRef.current) {
setLoading(false);
}
} catch (error) {
console.log("error", error);
}
}
The problem I'm facing:我面临的问题:
return
part, the component gives a black-white space then renders the image, hence no such 'Loading...' is getting rendered on the screen.即使在return
部分使用条件语句后,组件也会给出一个黑白空间然后渲染图像,因此屏幕上不会渲染这样的“正在加载...”。Things I'm unsure about:我不确定的事情:
Kindly refer to Codesandbox link for the live demo/code: https://codesandbox.io/s/img-lazy-ke6zz现场演示/代码请参考 Codesandbox 链接: https://codesandbox.io/s/img-lazy-ke6zz
Any help in the right direction would be quite helpful.任何朝着正确方向的帮助都会非常有帮助。
You can use useEffect
better in this case;在这种情况下,您可以更好地使用useEffect
; you have a state loading
.你有一个 state loading
。 You should listen to when this value changes in your useEffect
.你应该听听你的useEffect
中这个值何时发生变化。
useEffect(() => {
setLoading(false);
}, [loading]);
The value you pass in the array in the useEffect hook is getting listened to (there can be more than value in here, as it's an array).您在 useEffect 钩子中传递给数组的值会被监听(这里可能不止值,因为它是一个数组)。 So when one of those values changes you run the code in useEffect.因此,当其中一个值发生更改时,您可以在 useEffect 中运行代码。 In this component loading
should only changes once to false.在这个组件中, loading
应该只更改一次为 false。 So whenever you use setLoading
in your code this useEffect is ran.因此,每当您在代码中使用setLoading
时,都会运行此 useEffect。
I recommend you read more about this hook here: https://reactjs.org/docs/hooks-effect.html我建议您在此处阅读有关此钩子的更多信息: https://reactjs.org/docs/hooks-effect.html
Also, I think it's better in this case, you default the loading
state to true instead of false.另外,我认为在这种情况下更好,您默认loading
state 为 true 而不是 false。 So when the component renders it is loading from the start.因此,当组件呈现时,它会从头开始加载。 In the start
function you can use setLoading
to false when src or fallback isn't set.在start
function 中,当 src 或 fallback 未设置时,您可以使用setLoading
为 false。 This is also why your fallback isn't being shown.这也是为什么您的后备没有显示的原因。 As you default loading
to false and you show the fallback when this is loading
is true.当您默认loading
为 false 时,您会在loading
为 true 时显示回退。
A better practice of using React.useEffect
and React.useState
is importing it in your file.使用React.useEffect
和React.useState
的更好做法是将其导入文件中。 This can be done as followed import React, { useRef, useEffect, useState } from "react";
这可以按照以下方式完成import React, { useRef, useEffect, useState } from "react";
. . Then you can use them like this const [loading, setLoading] = useState(false);
然后你可以像这样使用它们const [loading, setLoading] = useState(false);
without React prefixing it.没有 React 前缀。
You can find an edited version of your CodeSandbox here https://codesandbox.io/s/img-lazy-forked-l8zuf?file=/src/Image.js .您可以在https://codesandbox.io/s/img-lazy-forked-l8zuf?file=/src/Image.js找到 CodeSandbox 的编辑版本。 I also changed the returning statement, which you can do if you don't want to show errors.我还更改了返回语句,如果您不想显示错误,可以这样做。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.