在加载实际对象之前,使用Axios和useEffect提取数据将导致null。

不幸的是,在实际对象不为空之前,我无法使用对象分解。

我被迫使用一个钩子(Hook)来检查一个对象是否为空。

例如,我想创建多个函数并将我的代码拆分为单独的函数,以提高可读性。

这是我的HTTP请求Hook:

import { useState, useEffect } from 'react';

import axios from 'axios';

export const useHttp = (url, dependencies) => {
    const [isLoading, setIsLoading] = useState(false);
    const [fetchedData, setFetchedData] = useState(null);

    useEffect(() => {
        setIsLoading(true);

        axios
            .get(url)
            .then(response => {
                setIsLoading(false);
                setFetchedData(response.data);
            })
            .catch(error => {
                console.error('Oops!', error);
                setIsLoading(false);
            });
    }, dependencies);

    return [isLoading, fetchedData];
};

其次是我的页面组件:
import React from 'react';

import { PAGE_ABOUT, API_URL } from 'constants/import';

import Header from './sections/Header';
import Main from './sections/Main';
import Aside from './sections/Aside';

import { useHttp } from 'hooks/http';

const About = () => {
    const [isLoading, about] = useHttp(PAGE_ABOUT, []);

    if (!isLoading && about) {
        return (
            <section className="about">
                <div className="row">
                    <Header
                        featuredImage={API_URL + about.page_featured_image.path}
                        authorImage={API_URL + about.page_author_image.path}
                        authorImageMeta={about.page_author_image.meta.title}
                        title={about.about_title}
                        subtitle={about.about_subtitle}
                    />

                    <Main
                        title={about.page_title}
                        content={about.page_content}
                    />

                    <Aside
                        title={about.about_title}
                        content={about.about_content}
                    />
                </div>
            </section>
        );
    }
};

export default React.memo(About);

实际的问题是我无法在实际返回对象之前嵌套函数。

有没有办法在没有检查的情况下获取数据?或者更清洁的解决方案会有所帮助。

我想使用多个组件来拆分代码。

任何意见或建议将不胜感激。

最佳答案

您的要求对UI不利。在获取数据时,您不想阻止UI呈现。因此,通常的做法是显示“正在加载”微调器,或者(如果您指望的是快速的请求)仅显示任何内容,直到弹出为止。

因此,您将获得以下内容:

const About = () => {
    const [isLoading, about] = useHttp(PAGE_ABOUT, []);

    if (isLoading) return null; // or <Loading />

    return (
       <section className="about">
            <div className="row">
                <Header
                    featuredImage={API_URL + about.page_featured_image.path}
                    authorImage={API_URL + about.page_author_image.path}
                    authorImageMeta={about.page_author_image.meta.title}
                    title={about.about_title}
                    subtitle={about.about_subtitle}
                />

                <Main
                  title={about.page_title}
                  content={about.page_content}
                />

                <Aside
                  title={about.about_title}
                  content={about.about_content}
                />
            </div>
        </section>
    );
};

如果您的api无法防止错误,并且您担心自己的为空未定义,则可以使用Error Boundary组件包装该组件并显示默认错误。但这取决于您是否在应用程序中使用它们。

09-19 13:57