美文网首页
在Suspense结合使用取数逻辑

在Suspense结合使用取数逻辑

作者: 你的时间非常值钱 | 来源:发表于2020-07-15 18:45 被阅读0次

react在16.6推出了<Suspense>组件,看了官方文档和一些分析文章,发现以后react的开发方式将会发生重大改变

Suspense功能

声明方式等待任何内容(组件),包括数据,替代react-loadable做code spliting

Suspense 常见API

1.fallback:Suspense里面还有"任务"执行时展示的UI
2.children: 一般是异步组件(配合lazy包裹的异步组件),为什么说一般是,因为官方没提供稳定的api来将取数逻辑跟Suspense配合出延迟效果,但我们可以hack

异步加载组件使用lazy(<MyComponent />)就一定要Suspense包裹,看了一些分析Suspense源码的文章,了解到Suspense内部是利用componentDidCatch来捕获到lazy主动throw出来的Promise来做条件渲染,渲染fallback内容,待lazy内的Promise状态resolve,完整内容就渲染出来

// lazy内部也是返回了Promise对象
const AsyncCompnentA = lazy(() => import('../componentA'))
export default () => {
  return (
    <Suspense fallback={<Loading />}>
       <AsyncCompnentA  />
    </Suspense>
 )
}

简易理解中的Suspense源码

class Suspense extends React.Component {
  state = {
     promise: null
  }
  componentDidCatch(e) {
    if(e instanceof Promise) {
        this.setState({
         promise: e,
       }, () => {
        e.then(() => {
           promise: null
        })
      })
    }
  }
  render() {
      return this.state.promise ? this.props.fallback : this.props.children
   }
}

不难理解,通过componentDidCatch捕获的异常改变自身state,然后凭借promise值做条件渲染

而官方没提供取数延迟,貌似暂时只开放给请求库(swr)而非大众调用者,但分析了一波源码,利用throw promise也是可以模拟的

const PromiseThrower = () => {
  const getData = () => {
    const getData = fetch()
    getData.then(data => {
      returnData = data
    })
    if (returnData === cache) {
      throw getData
    }
    return returnData
  }
  return <>{getData()}</>
}

// useage
export default () => {
  return (
    <Suspense fallback={<Loading />}>
      <PromiseThrower />
    </Suspense>
  )
}

以往取数组件逻辑

以往loading跟取数(网络请求)完全耦合,三目渲染、样板代码写到吐

const AsyncComponentC = () => {
  const [loading, setLoading] = useState(false)
  useEffect(() => {
      setLoading(true)
      fetch('xxx').then(() => {
        setLoading(false)
     })
  }, [])
 return loading ? <Loading /> : <RealComponent />
}

未来使用猜想

对于一些短命组件,实时性强且跟应用其它组件少联系的组件,我们大可将数据流范围从应用级(redux之类)收窄至组件本身state,这样让组件更加single,而我们自行封装的取数逻辑(hook)可以在axios,fetch甚至原生xhr上二次封装,在里面loading状态时throw个promise就可以在<Supense>里有延迟效果了

// usage
const AsyncComponentA = () => {
    const { data } = useFetch('api1')  // 自己封装取数逻辑
    return (
       <div>{data.whatthe}</div>
    )
}
const AsyncComponentB = () => {
    const { data } = useFetch('api2')  // 自己封装取数逻辑
    return (
       <div>{data.whatthe}</div>
    )
}

<Suspense fallback={<Loading />}>
   <AsyncComponentA />
   <AsyncComponentB />
</Suspense>

Suspense和改造过的取数hook能带来什么效果

1.loading逻辑和 UI 解耦
2.Suspense可以嵌套使用,声明方式时加载状态顺序可控
3.竞态更加可控

参考文献
1.https://zh-hans.reactjs.org/docs/concurrent-mode-suspense.html#what-if-i-dont-use-relay
2.https://juejin.im/post/5c7d4a785188251b921f4e26#heading-5

相关文章

  • 在Suspense结合使用取数逻辑

    react在16.6推出了 组件,看了官方文档和一些分析文章,发现以后react的开发方式将会发生重大改变 Sus...

  • 2022-05-11

    React suspense 与 lazy 结合 最近给页面增加骨架屏功能,使用了React的suspense功能...

  • HR取数逻辑

    HR-员工所属组,部门,上层部门 OBJID即为部门编号 获取考勤信息 对应的前台Tcode:PT66 每个月有一...

  • 深度理解 React Suspense(附源码解析)

    本文介绍与 Suspense 在三种情景下使用方法,并结合源码进行相应解析。欢迎关注个人博客。 Code Spli...

  • 口径、维度、指标

    口径是取数逻辑(如何取数的),比如要取的数是10岁以下儿童中男孩的平均身高。维度是我取数的依据字段:年龄、性别、身...

  • 基准测试(三)

    结合应用。 业务逻辑很简单:只是简单的查询。 使用的最大连接数数是20。 使用ab进行压测。测试结果:并发数100...

  • pandas&numpy使用技巧

    1.dataframe取数 1)列名直接取数 2)ix或者切片 3)利用逻辑运算返回数据位置

  • HOOK

    Suspense

  • React 新特性 lazy&Suspense 及相关错误处理

    lazy&Suspense 基本使用 JS 模块延时加载,做代码拆分 使用 React生命周期 拦截组件加载失败 ...

  • 使用random实现随机动画

    使用随机颜色,随机位置,实现动画 生成随机数方案 传统方式 使用随机数方式 特殊方式 使用random结合toSt...

网友评论

      本文标题:在Suspense结合使用取数逻辑

      本文链接:https://www.haomeiwen.com/subject/ordxhktx.html