在初始页面加载时在 Next.js 中获取整个应用程序的全局数据

Ser*_*kov 7 javascript reactjs next.js

在我的 Next.js 应用程序中,我有搜索过滤器。过滤器由复选框组成,为了呈现这些复选框,我需要从 API 获取(GET)所有可能的选项。

这些过滤器在许多页面上都可用,因此无论用户进入哪个页面,我都需要立即获取过滤器的数据并将其放入本地存储中,以避免进一步过多的 API 调用。将 API 调用放在每个页面中不是一种选择。

我看到一个选项是将 API 调用放入getInitialProps_app.js,但是根据Next.js 文档,自动静态优化将不起作用,我的应用程序中的每个页面都将在服务器端呈现。

那么在 Next.js 中获取此类全局数据的正确方法是什么?

- - - - 更新

所以此时我使用了下一个解决方案:在 _app.js 中我放置了useEffectReact Hook,一旦前端准备好,我就会检查整个应用程序的数据是否在区域设置存储中。如果不是,则从服务器获取数据并放入本地存储以供进一步使用。

// _app.js
const AppWrapper = ({ children }) => {
    const dispatch = useAppDispatch();

    useEffect(() => {
        dispatch({ type: FRONTEND_LOADED });
        loadInitialData(dispatch);
    }, [false]);

    return <>{children}</>;
};

class MyApp extends App {
    render() {
        const { Component, router, pageProps } = this.props;

        return (
            <>
                <AppProvider>
                    <AppWrapper>
                        <MainLayout pathname={router.pathname}>
                            <Component {...pageProps} />
                        </MainLayout>
                    </AppWrapper>
                </AppProvider>
            </>
        );
    }
}
Run Code Online (Sandbox Code Playgroud)
// loadInitialData.js
import {
    SET_DIETS_LIST,
    UPDATE_FILTERS_FROM_CACHE,
} from "Store/types";
import fetch from "isomorphic-unfetch";

export default dispatch => {
    const ls = JSON.parse(localStorage.getItem("filters"));
    if (ls) {
        const localStorageState = {
            diet: {
                list: ls.diet.list || [],
                selected: ls.diet.selected || [],
            },
            ...
        };
        dispatch({
            type: UPDATE_FILTERS_FROM_CACHE,
            payload: { filters: localStorageState },
        });
    }

    if (!ls || !ls.diet.list.length) {
        fetch(`${process.env.API_URL}/diets`)
            .then(r => r.json())
            .then(data => {
                dispatch({ type: SET_DIETS_LIST, payload: { data[0] } });
            });
    }
...
};

Run Code Online (Sandbox Code Playgroud)

Dar*_*ert 0

这个过滤器似乎位于标题菜单或侧边栏菜单上?

如果是这种情况,我建议(_app.js 之外的选项)将 API 调用者放在 header/sidebar 组件中,并在布局/pages 组件上调用 header/sidebar 组件。

因此,您将获得与您所描述的相同的行为(不在每个页面上调用 SSR,并且静态优化仍然有效,因为该概念与 _app.js 类似(只需将其放入结构中)。