React18中请求数据的官方姿势适用其他框架

 更新时间:2022年07月13日 08:33:36   作者:魔术师卡颂  
这篇文章主要为大家介绍了官方回答在React18中请求数据的正确姿势详解,同样也适用其他框架,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

引言

一些同学喜欢在useEffect中请求初始数据,类似这样:

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

React18并不推荐这种方式。

这么写有什么问题?如果不推荐这种方式,那么推荐的方式是什么呢?

本文来看看Danreddit是如何回答上述问题的。

这是一个普遍的问题

除了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.jsRemix接管数据请求。

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

这些成熟的方案都致力于解决上述提到的问题。

如果不想使用这些方案,想自己写,可以参考React新文档中下面两篇文章:

使用effect同步数据

你可能不需要使用effect

想看中文的同学,可以看我写的总结 —— React新文档:不要滥用effect哦

总结

本文我们聊了React18之后不推荐的请求数据的方式以及推荐的请求数据的方式。

其中不推荐的请求数据的方式不仅存在于React中,很多前端框架都有这样的问题。

以上就是React18中请求数据的官方姿势适用其他框架的详细内容,更多关于React18请求数据的资料请关注脚本之家其它相关文章!

相关文章

  • React Native悬浮按钮组件的示例代码

    React Native悬浮按钮组件的示例代码

    本篇文章主要介绍了React Native悬浮按钮组件的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起看看吧。
    2018-04-04
  • react组件中的constructor和super知识点整理

    react组件中的constructor和super知识点整理

    这篇文章主要介绍了react组件中的constructor和super知识点整理,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-08-08
  • react路由配置方式详解

    react路由配置方式详解

    本篇文章主要介绍了react路由配置方式详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • React路由的history对象的插件history的使用解读

    React路由的history对象的插件history的使用解读

    这篇文章主要介绍了React路由的history对象的插件history的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-10-10
  • react 组件实现无缝轮播示例详解

    react 组件实现无缝轮播示例详解

    这篇文章主要为大家介绍了react 组件实现无缝轮播示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10
  • React中的useState如何改变值不重新渲染的问题

    React中的useState如何改变值不重新渲染的问题

    这篇文章主要介绍了React中的useState如何改变值不重新渲染的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • react-native 完整实现登录功能的示例代码

    react-native 完整实现登录功能的示例代码

    本篇文章主要介绍了react-native 完整实现登录功能的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • 浅谈React高阶组件

    浅谈React高阶组件

    这篇文章主要介绍了浅谈React高阶组件,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-03-03
  • 使用Node搭建reactSSR服务端渲染架构

    使用Node搭建reactSSR服务端渲染架构

    这篇文章主要介绍了使用Node搭建reactSSR服务端渲染架构,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • 基于React实现倒计时功能

    基于React实现倒计时功能

    这篇文章主要为大家详细介绍了如何基于React实现倒计时功能,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以参考一下
    2024-02-02

最新评论