资讯专栏INFORMATION COLUMN

在其他框架中也可以应用到React18中请求数据的官方姿势

3403771864 / 465人阅读

  首先我来说下在useEffect中请求初始数据,如下所示:

  useEffect(() => {
  fetch(xxx).then(data => setState(data.json()))
  }, [])

  这种方式到了React18并不适用。

  那如果这种方法不行,要推荐的又是那种方式?

  本文来看看Dan在reddit是如何回答上述问题的。

  这是一个普遍的问题

  除了React外,大部分以组件形式组织的前端框架,都有如下类似的API:

  effect

  didMount/didUpdate

  当在初始化时请求数据的需求,框架基本上执行的都是回调函数内请求操作,并在数据返回后更新状态。

  但就有这么一个特立独行,就是React。相反,他很普遍。

  React“独特”,是因为React官方在引导开发者不要用这种形式书写代码(通过严格模式下useEffect执行两次放大这个问题)。

  而React之这样做,是为了项目的性能以及UX(User Experience,用户体验)。

  现在来说说影响。注意,这些影响同样适用于其他框架。

  但这样写为什么不被推荐?

  需要解决竞态问题

  在useEffect中请求数据要面临的第一个问题是需要解决竞态问题

  假设你有个组件User,接收userID作为props,用userID请求数据后展示用户信息。

  下面是你的写法:

  function User({userID}) {
  const [data, setData] = useState(null);
  useEffect(() => {
  const res = await fetch(`https://xxx/${userID}/`);
  setData(res.json());
  }, [userID]);
  if (data) {
  return <div>{data.name}</div>;
  }
  return null;
  }

  现在注意点就是开发阶段很难复现的bug—— 假如userID变化足够快,会发起多个不同的用户请求。

  这也决定最终展示哪个用户的数据,取决于哪个请求先返回。这就是请求的竞态问题

  点击返回按钮后重新请求数据

    假设用户跳转到新的页面后,之后又通过浏览器回退按钮回到当前页面,因此并不能立刻看到他跳转前的页面。

  反之,看到的可能是个白屏 —— 因为还需要重新执行useEffect获取初始数据。

  这个问题的本质原因是:没有初始数据的缓存。

  CSR时的白屏时间

  CSR(Client-Side Rendering,客户端渲染)时在useEffect中请求数据,在数据返回前页面都是白屏状态。

  瀑布问题

  在父子组件都依赖useEffect获取初始数据渲染,这样影响整个渲染流程如下:

  父组件mount

  父组件useEffect执行,请求数据

  数据返回后重新渲染父组件

  子组件mount

  子组件useEffect执行,请求数据

  数据返回后重新渲染子组件

  可见,当父组件数据请求成功后子组件甚至还没开始首屏渲染。

  这就是渲染中的瀑布问题 —— 数据像瀑布一样一级一级向下流动,流到的组件才开始渲染,很低效。

  useEffect的问题很多,那么有什么适用的好方式?

  好的方式

  在Meta公司内部,基于Relay驱动数据(但请求数据要求使用GraphQL),所以这套架构比较难在社区普及开。

  但是,现在社区已经有了成熟的请求数据的方案

  对于SSR,可以使用Next.js、Remix接管数据请求。

  对于CSR,可以使用React Query、useSWR接管数据请求。

  上述解决方案都是十分成熟,当然如果你有其他解决方案,建议参考React新文档中下面两篇文章:

  使用effect同步数据

  你可能不需要使用effect

  注意,中文可以看的总结,记住在React新文档:不要滥用effect哦

  最后,总结下其实React18之后不推荐的请求数据的方式以及推荐的请求数据的方式。其中不推荐的请求数据的方式这个现象不仅存在于React中,其他很多框架也都会出现这样问题。


文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/128099.html

相关文章

  • Locale深度解析

    摘要:特别是开发一些只做国内市场,只有中文的项目时,可能就直接被忽视了。应用场景的使用场景基本就是根据不同国家和语言,进行不同的显示。比如中解析时,可以同时处理两种格式。一组为,一组为。对于中文,英文,日文都有一个默认的匹配。 摘要 Locale是日常开发中比较容易忽视的技术点。特别是开发一些只做国内市场,只有中文的项目时,Locale可能就直接被忽视了。而且在项目提出多语言支持的时候,因为...

    spacewander 评论0 收藏0
  • Locale深度解析

    摘要:特别是开发一些只做国内市场,只有中文的项目时,可能就直接被忽视了。应用场景的使用场景基本就是根据不同国家和语言,进行不同的显示。比如中解析时,可以同时处理两种格式。一组为,一组为。对于中文,英文,日文都有一个默认的匹配。 摘要 Locale是日常开发中比较容易忽视的技术点。特别是开发一些只做国内市场,只有中文的项目时,Locale可能就直接被忽视了。而且在项目提出多语言支持的时候,因为...

    taowen 评论0 收藏0
  • 全栈最后一公里 - Node.js 项目线上服务器部署与发布

    摘要:没有耐心阅读的同学,可以直接前往学习全栈最后一公里。我下面会罗列一些,我自己录制过的一些项目,或者其他的我觉得可以按照这个路线继续深入学习的项目资源。 showImg(https://segmentfault.com/img/bVMlke?w=833&h=410); 本文技术软文,阅读需谨慎,长约 7000 字,通读需 5 分钟 大家好,我是 Scott,本文通过提供给大家学习的方法,...

    Nosee 评论0 收藏0
  • Taro 优秀学习资源汇总

    摘要:多端统一开发框架优秀学习资源汇总官方资源项目仓库官方文档项目仓库官方文档微信小程序官方文档百度智能小程序官方文档支付宝小程序官方文档字节跳动小程序官方文档文章教程不敢阅读包源码带你揭秘背后的哲学从到构建适配不同端微信小程序等的应用小程序最 Awesome Taro 多端统一开发框架 Taro 优秀学习资源汇总 showImg(https://segmentfault.com/img/r...

    toddmark 评论0 收藏0

发表评论

0条评论

3403771864

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<