当您注册/登录/刷新页面时,登录页面在进入正确页面之前闪烁.我试着把一个加载程序,但它所做的是做一个加载动画之前,它闪烁,然后go 正确的页面.知道如何避免这种情况发生吗?

function App(){
  const [user, setUser] = useState();
  const [loading, setLoad] = useState(true);
  useEffect(() => {
    const unsubscribe = onAuthStateChanged(getAuth(), setUser, setLoad(false))
    return () => {unsubscribe()}
  }, [])
const AuthenticatedRoute = ({children}) => {
  let isAuthenticated;
    if(user !=null){
      isAuthenticated = true;
    }else{
      isAuthenticated = false;
    }
    if(!loading){
      return isAuthenticated? children: <Navigate to="/signin"/>
    }else{
      return <Loading/>
    }
  
}

const UnauthenticatedRoute = ({children}) => {
  let isAuthenticated;
    if(user !=null){
      isAuthenticated = true;
    }else{
      isAuthenticated = false;
    }
    if(!loading){
      return !isAuthenticated? children: <Navigate to="/home"/>
    }else{
      return <Loading/>
    }
  
}

      return(
      <Router>
      <div className="App">
          {
          <Routes>
            <Route exact path="/" element={<UnauthenticatedRoute><PreHome/></UnauthenticatedRoute>}/>
            <Route path='/home' element={<AuthenticatedRoute><Home/></AuthenticatedRoute>} />
            <Route exact path="/signin" element={<UnauthenticatedRoute><Signin/></UnauthenticatedRoute>} />
            <Route exact path="/signup" element={<UnauthenticatedRoute><Signup/></UnauthenticatedRoute>} />
          </Routes>
          }
      </div>
      </Router>
      )
  }

注销代码:

<button onClick={() => signOut(getAuth())}>Sign Out</button>

登录代码:

async function OnFormSubmit(e){
        e.preventDefault();
        const auth = getAuth();
        try{
            isLoading(true);
            await signInWithEmailAndPassword(auth, email, pw)
            isLoading(false);
        }catch(err){
            console.log(err)
        }
    }

推荐答案

Issues

  1. 只有当onAuthStateChanged中出现错误时,加载状态才会被清除.
  2. 路由保护器组件被声明为另一个React组件.这是反模式.当每次父App个组件重新启动时声明这些组件的新"实例"时,它将卸载/装载组件的子树.
  3. 组件在决定重定向或呈现路由内容之前,不会等待用户的身份验证状态得到解决.

Solution

  • 自行移出路由保护器组件.为要渲染到的嵌套管线渲染Outlet.这允许您将其呈现为布局路由,而不是单个包装器组件.
  • 使用适当的"加载"状态.使用未定义的user状态作为"加载状态".

例子:

import { Outlet, Navigate } from 'react-router-dom';

const AuthenticatedRoute = ({ user }) => {
  if (user === undefined) return <Loading />;

  return user
    ? <Outlet />
    : <Navigate to="/signin" />;
};

const UnauthenticatedRoute = ({ user }) => {
  if (user === undefined) return <Loading />;

  return user
    ? <Navigate to="/home" />
    : <Outlet />;
};

...

function App(){
  const [user, setUser] = useState();

  useEffect(() => {
    const unsubscribe = onAuthStateChanged(getAuth(), setUser);
    return unsubscribe;
  }, []);

  return(
    <AuthContextProvider>
      <Router>
        <div className="App">
          <Routes>
            <Route element={<UnauthenticatedRoute user={user} />}>
              <Route path="/" element={<PreHome />} />
              <Route path="/signin" element={<Signin />} />
              <Route path="/signup" element={<Signup />} />
            </Route>
            <Route element={<AuthenticatedRoute user={user} />}>
              <Route path='/home' element={<Home />} />
            </Route>
          </Routes>
        </div>
      </Router>
    </AuthContextProvider>
  );
}

Javascript相关问答推荐

你怎么看啦啦队的回应?

如何调用名称在字符串中的实例方法?

使用Google API无法进行Web抓取

使用Nuxt Apollo在Piniastore 中获取产品细节

以编程方式聚焦的链接将被聚焦,但样式不适用

打字脚本中方括号符号属性访问和拾取实用程序的区别

WebSocketException:远程方在未完成关闭握手的情况下关闭了WebSocket连接.&#三十九岁;

将相关数据组合到两个不同的数组中

在渲染turbo流之后滚动到元素

Cherrio JS返回父div的所有图像SRC

用Reaction-RT-Chart创建实时条形图

TypeORM QueryBuilder限制联接到一条记录

Firebase函数中的FireStore WHERE子句无法执行

将匿名函数附加到链接的onClick属性

使用导航时,路径的所有子组件都必须是路径

如何将.jsx转换为.tsx

在Java脚本/类型脚本中覆盖父构造函数中的默认值

从D3 v3更新,没有错误,但输出SVG路径不可见

为什么它是Object.hasOwn(x,y)!==Reflect.ownKeys(X).如果x是CSSStyleClaimation对象,而y是像';z-index';这样的连字符属性,则包含(Y)?

Jsyaml SafeDump打字支持