react中解决异步
介绍 (Introduction)
Traditionally, dealing with asynchronous code in React has required some boilerplate:
传统上,在React中处理异步代码需要一些样板:
Make a wrapper component to show a pending or rejected state.
使包装器组件显示挂起或拒绝状态。
Make our components keeping track of pending and rejected state and inform the wrapper component about state changes.
让我们的组件跟踪挂起和拒绝的状态,并通知包装器组件状态更改。
But ideally, we want:
但理想情况下,我们希望:
To care only about the fulfilled state in our components.
只关心组件中的实现状态。
To abstract away the pending and rejected state.
提取挂起和拒绝状态。
Here, I am going to show you how to achieve just that and how to structure asynchronous code in a modern way.
在这里,我将向您展示如何实现这一目标以及如何以现代方式构造异步代码。
工具类 (Tools)
We are going to use the Suspense component and Error Boundaries. They have been available since React 16.6.
我们将使用Suspense组件和Error Boundaries。 从React 16.6开始就可以使用它们。
悬念 (Suspense)
The Suspense component will display a fallback
user interface until all of its children will have their state fulfilled:
Suspense组件将显示fallback
用户界面, 直到其所有子级都达到其状态为止 :
<Suspense fallback="Waiting...">
<ChildComponent1 />
<ChildComponent2 />
</Suspense>
错误边界 (Error Boundary)
From now on, I am going to use the Exception component as an Error Boundary implementation. It will display a fallback
user interface if any of its child components will throw
an exception:
从现在开始,我将使用Exception组件作为Error Boundary实现。 它会显示一个fallback
的用户界面,如果任何其子组件将throw
一个异常:
<Exception fallback="An error has occurred!">
<ChildComponent1 />
<ChildComponent2 />
</Exception>
例 (Example)
Suppose we want to fetch users’ data from a remote resource:
假设我们要从远程资源中获取用户的数据:
const fetchUsers = async () => {const response = await fetch(
"https://jsonplaceholder.typicode.com/users"
);const users = await response.json();
console.log("Users data", users);return users;
};
I will use makeSuspendableHook to integrate our asynchronous code within Suspense and Error boundary:
我将使用makeSuspendableHook在Suspense和Error边界内集成我们的异步代码:
const useUsers = makeSuspendableHook(fetchUsers());
In our component, all we should care about is the actual data and its representation:
在我们的组件中,我们只需要关心实际数据及其表示即可:
const Users = () => {const users = useUsers();return (
<div>
List fetched users:
<ul>
{users.map(({ name }) => (
<li>{name}</li>
))}
</ul>
</div>
);
}
Finally, we will wrap everything together:
最后,我们将所有内容包装在一起:
export default () => (
<Exception fallback="An error has occurred">
<Suspense fallback="Waiting...">
<Users />
</Suspense>
</Exception>
);
Play with web example at codesandbox.io
Play with native example at snack.expo.io
That is it!
这就对了!
细节 (Details)
The Suspense and Error Boundaries are like try-catch
blocks for components.
Suspense和Error Boundaries类似于组件的try-catch
块。
The Suspense will
catch
any promise. It will wait until the promise will be fulfilled rendering its children or in case of the promise being rejected it willthrow
the rejection value.悬念将
catch
任何承诺。 它会等到承诺将履行其渲染子女或承诺存在的情况下, 拒绝将throw
拒绝值。The Error Boundary will
catch
anything.错误边界将
catch
任何内容。
Here is what hypothetical code might look like
假设的代码如下所示
try {
<Component1 />
<Component2 />
}catch (promise) {
<i>Waiting...</i> // until promise will be settled
}catch (anything) {
<b>An exception: "{anything}" has occurred!</b>
}
Therefore you should enclose the Suspense within Error Boundary and not vice versa, as the Error Boundary will catch a promise before the Suspense.
因此,您应该将暂挂状态包含在“错误边界”内,而不是反之,因为“错误边界”将在暂挂状态之前兑现承诺。
Of course, you can make many layers of nesting of Suspense and Error Boundaries, fine-tuning the desired outcome.
当然,您可以对悬念和错误边界进行多层嵌套,以微调所需的结果。
This throw
and catch
mechanics will only work during React’s rendering phase. So if you will try to throw
in some event, it will not work. You can useEventThrow in this case.
throw
和catch
机制仅在React的渲染阶段起作用。 因此,如果您尝试throw
某些事件,它将无法正常工作。 在这种情况下,您可以使用EventThrow 。
Thank you!
谢谢!
翻译自: https://medium.com/@imixaly4/managing-asynchronous-code-in-react-3ccd7feaf208
react中解决异步