了解挂起和反应挂钩

问题描述

我正在努力使用 Suspense React hooks 查找问题。

下面的React代码存在几个关键问题

import { Suspense,useState,useEffect } from 'react';

const SuspensefulUserProfile = ({ userId }) => {
  const [data,setData] = useState({});
  useEffect(() => {
    fetchUserProfile(userId).then((profile) => setData(profile));
  },[userId,setData])
  return (
    <Suspense>
      <UserProfile data={data} />
    </Suspense>
  );
};
const UserProfile = ({ data }) => {
  return (
    <>
      <h1>{data.name}</h1>
      <h2>{data.email}</h2>
    </>
  );
};
const UserProfileList = () => {
  <>
    <SuspensefulUserProfile userId={1} />
    <SuspensefulUserProfile userId={2} />
    <SuspensefulUserProfile userId={3} />
  </>
};

让我知道它们是什么。

我发现了两个关键问题。

  • setdata依赖项数组中滥用useEffect
  • 没有提供suspense fallback道具。

我认为仍然存在一个关键问题。

奇怪的是,为什么userId必须包含在依赖项数组中。

解决方法

您误用了class _CreatePostScreenState extends State<CreatePostScreen> { @override Widget build(BuildContext context) { return Scaffold( appBar: MyAppBar(),body: Center( child: Text("Hello"),)); } } 的核心内容,至少直到可以用于数据提取的悬念为止。

暂挂目前仅适用于Suspense组件,不适用于您的应用程序的任意“加载”状态。例如,React应该如何确定您的React.lazy正在加载?

data的唯一用途是允许在React加载惰性组件时显示一些后备。对于其他类型的延迟加载应用程序数据,您可以实现自己的后备,如:

Suspense
,

主要问题是,您需要使用所谓的Suspense integration来执行数据获取并与<Suspense>组件进行接口。

通常,<UserProfile>组件会consume a resource synchronously(在这种情况下为您的data)并在资源不可用时将其悬空 ,从而导致{ {1}}临时呈现其<Suspense>道具(您尚未指定)。当资源可用时,fallback将重新呈现,并且消耗的资源将同步返回。

我已经发布了一个名为suspense-service的Suspense集成,它允许您使用封装了React Context API的服务来消耗异步函数定义的资源。

在下面的<UserProfile>演示中,通过稍微修改示例代码:

suspense-service
// import { Fragment,Suspense } from 'react';
const { Fragment,Suspense } = React;
// import { createService,useService } from 'suspense-service';
const { createService,useService } = SuspenseService;

const fetchUserProfile = userId => {
  return new Promise(resolve => {
    setTimeout(resolve,1000 + Math.random() * 1000);
  }).then(() => {
    return {
      name: `User ${userId}`,email: `user${userId}@example.com`
    };
  });
};

const UserProfileService = createService(fetchUserProfile);

const SuspensefulUserProfile = ({ userId }) => {
  return (
    <UserProfileService.Provider request={userId}>
      <Suspense fallback={<h1>Loading User Profile...</h1>}>
        <UserProfile />
      </Suspense>
    </UserProfileService.Provider>
  );
};

const UserProfile = () => {
  const data = useService(UserProfileService);

  return (
    <Fragment>
      <h1>{data.name}</h1>
      <h2>{data.email}</h2>
    </Fragment>
  );
};

const UserProfileList = () => {
  return (
    <Fragment>
      <SuspensefulUserProfile userId={1} />
      <SuspensefulUserProfile userId={2} />
      <SuspensefulUserProfile userId={3} />
    </Fragment>
  );
};

ReactDOM.render(<UserProfileList />,document.getElementById('root'));