在 React 路由器的加载器中使用延迟

问题描述 投票:0回答:0

这是我的装载机

  // fetch user data from Firebase
  auth.onAuthStateChanged((user) => {
    if (user) {
      userInfo.email = user?.email;
      userInfo.uid = user?.uid;
      userInfo.userName = user?.displayName;
      userInfo.userPhoto = user?.photoURL;
    } else {
      throw json({ message: 'No user founded!' }, { status: 403 });
    }
  });
  return userInfo;
}

async function getUserData(inputType) {
  const userInfo = {};

  const userRef = collection(db, inputType);
  const docRef = query(userRef, auth?.currentUser?.uid);
  const docSnap = await getDocs(docRef);

  const mappedData = docSnap.docs.map((doc) => ({
    id: doc.id,
    data: doc.data(),
  }));

  const user = mappedData.find((user) => user.id === auth?.currentUser?.uid);

  if (inputType === 'phone') {
    userInfo.phone = user?.data.phone;
    return userInfo.phone;
  }
  if (inputType === 'adress') {
    userInfo.adress = user?.data.adress;
    return userInfo.adress;
  }
  if (inputType === 'payment') {
    userInfo.payment = user?.data;
    return userInfo.payment;
  }
  if (inputType === 'photoProp') {
    userInfo.photoProp = user?.data;
    return userInfo.photoProp;
  }
}

export async function loader() {
  return defer({
    authInfo: await getAuthInfo(),
    phone: getUserData('phone'),
    adress: getUserData('adress'),
    payment: getUserData('payment'),
    photoProp: await getUserData('photoProp'),
  });
}

块引用

块引用

这个组件通过useLoaderData使用loaderData


import React, { Suspense } from 'react';
import { Link, Await, useLoaderData } from 'react-router-dom';

import styled from './AccountNavigation.module.css';

const AccountNavigation = () => {
  const { adress, phone, payment, authInfo } = useLoaderData();

  return (
    <div className={styled['account-navigation']}>
      <Suspense fallback={<p className='centered'>Loading...</p>}>
        <Await resolve={phone}>
          {(phone) => (
            <Link to='?mode=account-details&nav=phone' className={styled.infos}>
              <span className={styled.titles}>Phone Number : </span>
              {phone
                ? `0${
                    phone.substring(0, 3) +
                    '-' +
                    phone.substring(3, 6) +
                    '-' +
                    phone.substring(6)
                  }`
                : null}
            </Link>
          )}
        </Await>
      </Suspense>
      <Suspense fallback={<p className='centered'>Loading...</p>}>
        <Await resolve={adress}>
          {(adress) => (
            <Link
              to='?mode=account-details&nav=adress'
              className={styled.infos}
            >
              <span className={styled.titles}>Adress : </span>
              {adress}
            </Link>
          )}
        </Await>
      </Suspense>

      <Suspense fallback={<p className='centered'>Loading...</p>}>
        <Await resolve={authInfo}>
          {(authInfo) => (
            <Link to='?mode=account-details&nav=email' className={styled.infos}>
              <span className={styled.titles}>Email : </span>
              {authInfo.email}
            </Link>
          )}
        </Await>
      </Suspense>

      <Suspense fallback={<p className='centered'>Loading...</p>}>
        <Await resolve={payment}>
          {(payment) => (
            <Link
              to='?mode=account-details&nav=payment-details'
              className={styled.infos}
            >
              <span className={styled.titles}>Payment Details : </span>
              {payment?.cardNumber}
            </Link>
          )}
        </Await>
      </Suspense>
    </div>
  );
};

export default AccountNavigation;

这段代码有几个问题:

  1. 当我使用 defer 时,我不想等待电话、地址和付款,但是当我不等待时,它总是显示正在加载...(来自 Suspense)并且它们的数据永远不会到达。
  2. 如果我想在 Await resolve 中使用来自 loaderData 的多个变量,则在 await 中。我必须等待我在解析中使用的所有变量。还有别的办法吗?
  3. 我是否使用了正确的结构来使用等待和延迟?

我想要的是我不等待电话、地址和付款。当数据从后端到达时,我希望加载结束并显示给数据。当我打开我的页面时,由于页面看起来不错,我应该等待 getAuthInfo 和 photoProp。但是等待每一个想法都是需要时间的,这会造成一秒钟的黑屏,这是我不想给用户看的。

reactjs react-router-dom loader resolve react-suspense
© www.soinside.com 2019 - 2024. All rights reserved.