我正在努力使用 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
必须包含在依赖项数组中。
答案 0 :(得分:8)
您误用了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
答案 1 :(得分:4)
主要问题是,您需要使用所谓的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'));