我有一个应用程序,人们可以访问该网站,如果没有登录,但他们应该能够访问"/app","/app/*"只有在认证.我下面的代码可以工作,但由于某种原因,在显示消息"you're not allowed to..."之前,显示"/app"的内容有半秒或一秒.你知道为什么会这样吗?

import { Provider, useDispatch, useSelector } from 'react-redux';
import { useRouter } from 'next/router';
import '../styles/front.css';
import '../styles/app.css';
import React, { useEffect, useState } from 'react';
import { wrapper, store } from '../store';
import { login, logout, selectUser } from "../redux/slices/userSlice";
import { auth } from '../firebase';

function MyApp({ Component, pageProps }) {
  const user = useSelector(selectUser);
  const dispatch = useDispatch();
  const router = useRouter();
  const isAppPage = router.pathname.startsWith('/app');
  const [shouldRender, setShouldRender] = useState(true); // New state variable
  const [loading, setLoading] = useState(true);
  const [isAuthenticated, setIsAuthenticated] = useState(false);

  useEffect(() => {
    const unsubscribe = auth.onAuthStateChanged((userAuth) => {
      if (userAuth) {
        dispatch(login({
          email: userAuth.email,
          uid: userAuth.uid,
          displayName: userAuth.displayName,
          photoUrl: userAuth.photoURL
        }));
        setIsAuthenticated(true);
      } else {
        if (isAppPage) {
          setShouldRender(false);
        }
        dispatch(logout());
        setIsAuthenticated(false);
      }
      setLoading(false); // Set loading to false once the authentication status is checked
    });

    return () => unsubscribe(); // Cleanup the event listener when the component unmounts
  }, []);

  return (
    <Provider store={store}>
      {shouldRender ? <Component {...pageProps} /> : <p>You're not allowed to access that page.</p>}
    </Provider>
  );
}

export default wrapper.withRedux(MyApp);

推荐答案

您基本上需要一个具有第三个值的条件,该条件既不是"显示内容",也不是"您看不到此内容".类似于"挂起"状态,有条件地既不呈现Component文本,也不呈现"You're not allowed to access that page."文本.

初始的shouldRender状态与您不想立即渲染的这两个状态之一相匹配.从undefined开始,显式判断并有条件地返回NULL或加载指示符等. 示例:

function MyApp({ Component, pageProps }) {
  const user = useSelector(selectUser);
  const dispatch = useDispatch();
  const router = useRouter();
  const isAppPage = router.pathname.startsWith('/app');

  const [shouldRender, setShouldRender] = useState(); // initially undefined

  const [loading, setLoading] = useState(true);
  const [isAuthenticated, setIsAuthenticated] = useState(false);

  useEffect(() => {
    const unsubscribe = auth.onAuthStateChanged((userAuth) => {
      if (userAuth) {
        dispatch(login({
          email: userAuth.email,
          uid: userAuth.uid,
          displayName: userAuth.displayName,
          photoUrl: userAuth.photoURL
        }));
        setIsAuthenticated(true);
        setShouldRender(true); // <-- show the content
      } else {
        if (isAppPage) {
          setShouldRender(false); // <-- hide content
        }
        dispatch(logout());
        setIsAuthenticated(false);
      }
      setLoading(false);
    });

    return () => unsubscribe();
  }, []);

  if (shouldRender === undefined) {
    return null; // or loading indicator/spinner/etc
  }

  return (
    <Provider store={store}>
      {shouldRender
        ? <Component {...pageProps} />
        : <p>You're not allowed to access that page.</p>
      }
    </Provider>
  );
}

Javascript相关问答推荐

在NextJS中使用计时器循环逐个打开手风琴项目?

在具有焦点和上下文的d3多线图表中,如何将上下文的刷新限制在特定日期?

调用removeEvents不起作用

在JavaScript中声明自定义内置元素不起作用

如何从一个列表中创建一个2列的表?

阿波罗返回的数据错误,但在网络判断器中是正确的

在HTML语言中调用外部JavaScript文件中的函数

将内容大小设置为剩余可用空间,但如果需要,可在div上显示滚动条

从Nextjs中的 Select 项收集值,但当单击以处理时,未发生任何情况

SPAN不会在点击时关闭模式,尽管它们可以发送日志(log)等

按下单键和多值

自定义图表工具提示以仅显示Y值

MongoDB受困于太多的数据

Node.js错误: node 不可单击或不是元素

我怎样才能点击一个元素,并获得一个与 puppeteer 师导航页面的URL?

KeyboardEvent:检测到键具有打印的表示形式

如何创建一个for循环,用于计算仪器刻度长度并将其放入一个HTML表中?

如何从Reaction-Redux中来自API调用的数据中筛选值

如果我将高度设置为其内容的100%,则在Java脚本中拖动以调整面板大小时会冻结

如何格式化API的响应