【问题标题】:How to setup a function which gets app settings and sets it as localStorage before the page loads. (next.js)如何在页面加载之前设置一个获取应用程序设置并将其设置为 localStorage 的功能。 (下一个.js)
【发布时间】:2021-10-27 06:40:13
【问题描述】:

过去几天我一直在开发 Next.JS Web 应用程序,但遇到了一个问题。该应用程序有一个 API 调用 (/api/settings),它从数据库返回有关应用程序的一些设置。目前,我有一个函数可以返回这些设置并访问第一个组件:

App.getInitialProps = async () => {
    const settingsRequest = await fetch(
        `${process.env.NEXT_PUBLIC_API_URL}/api/settings`
    );
    const settingsResponse = await settingsRequest.json();

    return { settings: settingsResponse };
};

这确实有效,我可以将设置传递给组件,但这有两个问题:

  • 我需要将 prop 嵌套在许多组件中,才能到达我需要的组件
  • 每次重新加载/更改页面时都会运行此请求

基本上,我需要创建一个系统来执行此操作:

  • _app.tsxgetInitialProps 中运行一个函数来检查数据是否已经在localStorage 中,如果没有,则发出API 请求并更新localStorage
  • 具有可从自定义挂钩访问的 localStorage 值。

目前的问题是我无法从app.tsx getInitialProps 访问 localStorage。因此,如果有人可以在任何页面加载之前运行此功能,请告诉我。

谢谢!

【问题讨论】:

  • localstorage 是一个浏览器 API,getInitialProps 在服务器上运行,所以你不能从那里设置它,你必须从客户端 fetch 访问 localstorage
  • @sairaj 获取本地存储是什么意思?
  • 我的意思是无论您在getInitialProps 中拨打的任何fetch 电话,您都必须从客户端执行此操作,才能访问localstorage

标签: reactjs typescript api next.js local-storage


【解决方案1】:

我找到了一个解决方案,它可能是一个笨拙的解决方案,但我设法让它工作,它可能对试图实现类似目标的人有用:

首先我们需要为设置创建一个“管理器”:

export const checkIfSettingsArePresent = () => {
    const settings = localStorage.getItem("app_settings");
    if (settings) return true;
    return false;
};

export const getDataAndUpdateLocalStorage = async () => {
    const r = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/api/settings`);
    const response = await r.json();

    localStorage.setItem("app_settings", JSON.stringify(response));
};

创建后,我们可以添加一个 UseEffect 挂钩和一个运行我们函数的 useState 挂钩。

const [doneFirst, setDoneFirst] = useState<boolean>(false);

useEffect(() => {
    const settingsPreset = checkIfSettingsArePresent();
    if (performance.navigation.type != 1)
        if (settingsPreset) return setDoneFirst(true);
    const getData = async () => {
        await getDataAndUpdateLocalStorage();
        setDoneFirst(true);
    };
    getData();
}, []);

//any other logic

if (!doneFirst) {
    return null;
}

最后的 if 语句确保在函数之前不运行任何其他内容。

现在,无论何时热重载页面,您都会看到 localStorage app_settings 已使用 API 中的值更新/创建。

但是,为了从应用程序的其他部分更简单地访问它,我创建了一个挂钩:

import { SettingsType } from "@sharex-server/common";

export default function useSettings() {
    const settings = localStorage.getItem("app_settings") || {
        name: "ShareX Media Server",
    };

    //@ts-ignore
    return JSON.parse(settings) as SettingsType;
}

现在我可以从任何函数导入 useSettings 并访问我的设置。

【讨论】:

    猜你喜欢
    • 2020-12-01
    • 2016-09-05
    • 1970-01-01
    • 2017-08-15
    • 1970-01-01
    • 1970-01-01
    • 2013-11-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多