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

背景

慢慢在前端挖坑,各类框架都有接触学习,在学 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 库。

    171 引用 • 267 回帖 • 552 关注

广告 我要投放

欢迎来到这里!

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

注册 关于
请输入回帖内容 ...