React router dom 6.14 并延迟不等待数据

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

我使用react router dom 6.14并尝试使用defere、suspense和await,就像在他们的文档中一样,无论我做什么,似乎后备从未呈现。

这是我的代码。

//route.tsx
const router = createBrowserRouter([
    {
      path: "/",
      element: <App />,
      errorElement: <ErrorPage />,
      children: [
        {
          path: "/products/:category",
          element: <ProductsMain />,
          loader: (req) => getItems(req),
        },
        {
          path: "/settings",
          element: <SettingsComponent />,
        },
      ],
    },
    {
      path: "test",
      element: <TestComonenet />,
      errorElement: <ErrorPage />,
    },
  ]);


//loader 

export async function getItems(request: any, primaryStore: StoreEn, otherStores: StoreEn[]) {
  // const body = getBodyFromStorage();
 
  try {
    const url = `${urlBE}/products/${request.params.category}`;
    const data = serverAPI(url, body, "success"); // ===> its a promise
return defer(data:
  } catch (error: any) {
    throw new Error(error);
  }
}

/// 服务器 api 上的快捷方式:

const serverAPI = async (url: productsEP, body: any, description?: string) => {
  try {
    const response = await fetch(url, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(body),
    });
    if (!response.ok) {
      const { message } = await response.json();
      throw new Error(message);
    }
    const jsonData = await response.json();
    return { data: jsonData, error: null, description: description };
  } catch (error: any) {
    throw new Error(error);
  }
};

现在是 ProductsMain 组件:

const ProductsMain = () => {
  const [products, setProducts] = useState<any[]>([]);

  const data: any = useLoaderData();


  return (
<Suspense fallback={<p>Loader...</p>}
    <Await resolve={data} >
      {(data) => (
            <>
              <Products data={data}/>
              
            </>
          )}
    <Await />
</Suspense>
  );
};

不知何故,加载程序似乎从未发生过。而且数据只是一个承诺,我无法渲染它(尽管我得到状态代码为 200 的数据)

reactjs react-router-dom
2个回答
0
投票

对于此类问题,下面的代码可能会对您有所帮助。延迟应该按照您使用的方法来工作。因此,更改以下一些内容,可能会有效。

<React.Suspense fallback={<p>Loader...</p>}
        <Await resolve={data} >
          {(data) => (
                <>
                  <Products data={data}/>
                  
                </>
              )}
        </div>
        <Await />
    
    </React.Suspense>

愿这对你有帮助。


0
投票

将加载程序更改为以下内容..

//loader 

export type GetItemsType = {
  dataPromise: Promise<any>
}

export function getItems(request: any) 
{
  // const body = getBodyFromStorage();
  const url = `${urlBE}/products/${request.params.category}`;
  const deferredObj: GetItemsType = { dataPromise: serverAPI(url, body, "success") };
  return defer(deferredObj);
}

请注意省略了

try-catch
语句,因为应在
Await
组件中捕获并处理错误。还删除了
async
修饰符,因为加载器中没有等待任何 Promise。
defer()
参数应该是一个对象,并且它的属性可以像这样访问..

import { GetItemsType } from 'PATH-TO-(GetItemsType)'
const ProductsMain = () =>
{
  // const [products, setProducts] = useState<any[]>([]);
  const data = useLoaderData() as GetItemsType;

  <Suspense fallback={<p>Loader...</p>}
    <Await resolve={data.dataPromise} errorElement={<p>*** Error Message here ***</p>} >
      {
        (data: any) => (<Products data={data}/>)
      }
    <Await />
  </Suspense>
}

值得一提的是,我对

react-router-dom
的了解有些有限,我的回答是基于我所知道的,所以希望它有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.