next.js 如何在下一个应用程序中根据全局状态上下文有条件地呈现标题?

ncecgwcz  于 2023-02-12  发布在  其他
关注(0)|答案(1)|浏览(89)

我有一个下一个应用程序,我使用上下文来处理一些加载状态。当应用程序第一次启动时,一些加载动画显示,然后相应的值“Isloading”将在启动动画完成时为假。我使用了React上下文。我的问题是,当我在加载完成后记录“isLoading”的值时,它给我“真”,而其他页面内的日志给我正确的更新值是“假”。这将导致我的标题总是显示。我做错了什么吗?
下面是my _app.tsx:

export default function App({ Component, pageProps }: AppProps) {
  const loadingCtx = useContext(LoadingContext);
  console.log(loadingCtx.isLoading); // why this line gives me true while it's actually false and in every other pages it gives me false.
  return (
    <LoadingProvider>
      <ThemeProvider theme={theme}>
        {!loadingCtx.isLoading && <Header />}// here I want to load header
        <Component {...pageProps} />
        {!loadingCtx.isLoading && <Footer />}
      </ThemeProvider>
    </LoadingProvider>
  );
}

这是我的索引.tsx:

export default function Home() {
  const loadingCtx = useContext(LoadingContext);

  useEffect(() => {
    if (loadingCtx.isLoading) {
      loadingCtx.finishLoading(); // this sets isLoading to false after 4 seconds.
    }
  }, []);

  console.log(loadingCtx.isLoading); // I log this line in other pages and they also gives me the correct value which is false.

  return (
    <>
      <Head>
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <link rel="preconnect" href="https://fonts.googleapis.com" />
        <link rel="preconnect" href="https://fonts.gstatic.com" />
      </Head>
      <main>
        {loadingCtx.isLoading && <AnimatedLogo />}
        {!loadingCtx.isLoading && <Layout />}
      </main>
    </>
  );
}

背景如下:

type contextType = { isLoading: boolean; finishLoading: () => void };

const LoadingContext = React.createContext<contextType>({
  isLoading: true,
  finishLoading: () => {},
});

interface LoadingProviderProps {
  children: React.ReactNode;
}

export const LoadingProvider = ({ children }: LoadingProviderProps) => {
  const [loading, setLoading] = useState<boolean>(true);

  const finishLoading = () => {
    if (loading === true) {
      setTimeout(() => {
        setLoading(false);
      }, 4000);
    }
  };

  return (
    <LoadingContext.Provider
      value={{ isLoading: loading, finishLoading: finishLoading }}
    >
      {children}
    </LoadingContext.Provider>
  );
};

export default LoadingContext;
whlutmcx

whlutmcx1#

您正在访问提供程序外部的上下文,因此将始终获得默认值。
App组件未 Package 在LoadingProvider中。一种解决方案是将逻辑移到<Header/>中,以便它检查isLoading是否为true并相应地返回。

相关问题