背景
慢慢在前端挖坑,各类框架都有接触学习,在学 Svelte 的过程中看到了一个好玩的语法——await
块。然后我就寻思可不可以在 React 也实现这样的组件呢?因为总感觉类似于 ejs 的方式有点奇怪,然后就整出来了一个 @herberthe/react-await 这个库,挺好玩的。
在 Svelte 中
下面的这个是官方的示例
{#await promise}
<p>...waiting</p>
{:then number}
<p>The number is {number}</p>
{:catch error}
<p style="color: red">{error.message}</p>
{/await}
其中的 then 块和 catch 块都可以省去
在 React 中的实现
下面的例子来源于库的文档
<Await promise={promise}>
{/* Here are code for pending */}
<Then>
{/* Here are code for resolve */}
</Then>
<Catch>
{/* Here are code for reject */}
</Catch>
</Await>
完整的举例如下
interface ICustomResolveProps {
awaitvalue: any
}
const CustomResolve: FC<ICustomResolveProps> = ({ awaitvalue }) => <h1>{awaitvalue}</h1>
interface ICustomRejectProps {
awaiterror: any
}
const CustomReject: FC<ICustomRejectProps> = ({ awaiterror }) => <h1>{awaiterror}</h1>
const App: FC = () => {
const [promise, setPromise] = useState<Promise<unknown>>()
useEffect(() => {
const prom = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Data Here!")
}, 2000)
})
setPromise(prom)
}, [])
return (
<Await promise={promise}>
<h1>pending~</h1>
<p>waiting for values~</p>
<Then>
<CustomResolve />
</Then>
<Catch>
<CustomReject />
</Catch>
</Await>
)
}
实现思路
实现思路比较简单, 其实使用自定义 hook 包裹 promise 也可以很好实现同样的效果。这里的思路是通过分别向 Await
的子组件 Then
和 Catch
注入 props.awaitvalue
和 props.awaiterror
属性。然后再由 Then
和 Catch
向它们的子组件(除了字符串类型)分别注入了上述的属性(深度为 1),这样组件就可以拿到数据和错误信息了。
因为 props 和 states 的改变都会触发组件的渲染,因此通过 shouldComponentUpdate
手动进行了性能优化以避免了标签页崩溃的问题。
现在咱们也可以在 React 里面,使用类似于 Svelte Await Block 的语法了!
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于