8

fre 2 大招:内置 Suspense

 3 years ago
source link: https://zhuanlan.zhihu.com/p/358624196
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

fre 2 大招:内置 Suspense

俺,只想跪在床上娇喘,不想隔着网线叫唤

halo 大家好,我是 132,今天给 fre 提了一个很重要的 pr,也就是内置 Suspense 组件

过去我一直没有内置 Suspense,是因为我一直不知道这玩意和普通 loading 有什么区别

但是因为今年很流行 sssr,这玩意 Suspense 是前提,所以我不得不内置它

what is suspense?

import { lazy, Suspense } from 'fre'

const OtherComponent = lazy(() => import('./OtherComponent'));
 
function MyComponent() {
 return (
  <div>
   <Suspense fallback={<div>Loading...</div>}>
    <OtherComponent />
   </Suspense>
  </div>
 )
}

其实说白了是一种 loading 组件的“链表实现”,当渲染到 Lazy 组件的时候中断,然后链表回退到 Suspense 组件,并改变 child,渲染出 fallback 的内容

它包含了链表的中断、回退、更换指针,三种操作,所以被称之为“突破”

suspense 和 loading 组件的区别

实际上从功能上来说,suspense 组件和 loading 没有太多区别

因为 useEffect + setState 本身就是异步的

我之前写了个一个简单的外置实现

export function Suspense(props) {
  const [suspend, setSuspend] = useState(false)
  useEffect(current => {
    Promise.all(current.promises).then(() => setSuspend(true))
  }, [])
  return [props.children, !suspend && props.fallback]
}

是的你没看错,在 fre 中外置 suspense 实现也就二十行代码

<Suspense> 
  <template #default> 
    <article-info/> 
  </template> 
  <template #fallback> 
    <div>Loading…</div> 
  </template> 
</Suspense>

在 vue 或 preact 等同步框架中,他们没有链表不能回退,通常实现方式是设置两个占位,然后根据某个内置 state 标记来决定渲染某个占位

以上,就是普通 loading 组件的实现,对用户来说可以获得相似的功能,但本质不同

那么问题来了,如果内置,还是这么实现吗?

答案当然不是

export function Suspense(props){
  return props.children
}

内置只需要一行代码,哈哈哈哈哈,这种组件其实蛮多的,比如 Fragment 也是这样

在 fre 或 react 中,这被称为边界组件,意思是它只提供一个标记,然后和解调度的时候根据标记干活

这个工作其实就是在恰当时机回退和更换链表指针

也就是说,只需要在 Lazy 组件渲染的时候,回退到 Suspense 组件,并将 child 指针指向 fallback 即可

try{
  updateComponent(WIP) // 被 throw 打断
}catch(e){
  WIP = WIP.parent // 回退到 Suspense 组件
  WIP.child = WIP.props.fallback // 更换 child 指针
}

总结

大家肯定要问,为什么这么着急内置 suspense,说好的 1kb 呢?

这是因为今年大家都在搞流式 ssr,这玩意依赖 Suspense,我也想搞

另外,内置 suspense 意味着,这个功能我会自己维护了,大家可以放心使用

可惜的是这样一来就彻底 2kb 了,搞死嘞o(╥﹏╥)o

最后放一下 fre 的 github 地址,大家平时看 react 源码可以作为参考


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK