加载页面时不显示 React 中的加载组件

Loading component in React not displaying while page is loading

我有一个显示来自 API 的媒体的页面,并创建了一个加载组件以在 API 加载时显示加载状态。我能够让加载组件显示在显示 API 中的 1 个项目的页面上,但在我加载多个项目的另一个页面上它不显示。我将如何为此创建加载组件?

    export default function Explore() {
    const [media, setMedia] = useState([]);
    const [faves, setFaves] = useState([]);

    useEffect(() => {
        const abortController = new AbortController();
        const opts = { signal: abortController.signal };

        fetch(`https://api.nasa.gov/planetary/apod?api_key=${apiKey}&count=15`, opts)
            .then((response) => response.json())
            .then((data) => setMedia(data))
            .catch((error) => console.log(error.message));
        return () => abortController.abort();
    }, []);

    if (!media) return <Loading />;

    const addFave = (fave) => {
        const isAlreadyStarred = faves.filter(
            item => item === fave
        )

        if (isAlreadyStarred.length > 0) {
            return;
        }
        const newFavesList = [...faves, fave];
        setFaves(newFavesList);
        // saveToLocalStorage(newFavesList);
    };

    const removeFave = (e) => {
        const url = e.target.getAttribute("url")
        setFaves(faves.filter(favorite => favorite.url !== url));
    };

    return (...)

以不同的方式获取 API 时显示加载组件:

export default function Today() {
            const [mediaData, setMediaData] = useState(null);
        
            useEffect(() => {
                fetchMedia();
                async function fetchMedia() {
                    const res = await fetch(`https://api.nasa.gov/planetary/apod?api_key=${apiKey}`);
                    const data = await res.json();
                    setMediaData(data);
                    console.log(data);
                }
            }, []);
        
            if (!mediaData) return <Loading />;
        
            return (...)

![] 是假的。如果您将其更改为

if (!media.length) return <Loading />;

应该适合你

这是因为你用 [] 初始化了 media,这是一个真值,所以检查 if (!media) (![]) 将评估为 false

您可以使用 null 初始化 media,检查 !media.length 或更好地具有如下加载状态:

const [media, setMedia] = useState([])
const [loading, setLoading] = useState(false)

useEffect(() => {
        setLoading(true)

        const abortController = new AbortController();
        const opts = { signal: abortController.signal };

        fetch(`https://api.nasa.gov/planetary/apod?api_key=${apiKey}&count=15`, opts)
            .then((response) => response.json())
            .then((data) => setMedia(data))
            .catch((error) => console.log(error.message))
            .finally(() => setLoading(false));

        return () => abortController.abort();
    }, []);

if (loading) return <Loading />;

这样你也可以添加一条空消息:

const [media, setMedia] = useState([])
const [loading, setLoading] = useState(false)

useEffect(() => {
        setLoading(true)

        const abortController = new AbortController();
        const opts = { signal: abortController.signal };

        fetch(`https://api.nasa.gov/planetary/apod?api_key=${apiKey}&count=15`, opts)
            .then((response) => response.json())
            .then((data) => setMedia(data))
            .catch((error) => console.log(error.message))
            .finally(() => setLoading(false));

        return () => abortController.abort();
    }, []);

if (loading) return <Loading />;

if (!media || media.length < 1) return 'No data';