React 用 Await 组件来控制依赖 promise 的渲染

本贴最后更新于 1483 天前,其中的信息可能已经时异事殊

背景

慢慢在前端挖坑,各类框架都有接触学习,在学 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 的子组件 ThenCatch 注入 props.awaitvalueprops.awaiterror 属性。然后再由 ThenCatch 向它们的子组件(除了字符串类型)分别注入了上述的属性(深度为 1),这样组件就可以拿到数据和错误信息了。

因为 props 和 states 的改变都会触发组件的渲染,因此通过 shouldComponentUpdate 手动进行了性能优化以避免了标签页崩溃的问题。

现在咱们也可以在 React 里面,使用类似于 Svelte Await Block 的语法了!

  • React

    React 是 Facebook 开源的一个用于构建 UI 的 JavaScript 库。

    192 引用 • 291 回帖 • 370 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
HerbertHe
主营前端, 热衷于造轮子 ~ 现为西部计划服务新疆专项志愿者~ Nuco.Tech Studio 联合创始人 太原