React18 的 useEffect 新特性为什么被疯狂吐槽?

0a8a7f464bb84ffed0bd2988da0221f8.gif

作者 | 零一

来源 | 前端印象

react18 已经出来一段时间了,create-react-app 默认安装的 React 版本也已经是 18+,不知道有没有小伙伴发现自己有点看不懂 React 了?

import { useEffect, useState } from 'react'function App () {const [data, setData] = useState(0)useEffect(() => {setData(preData => preData + 1)}, [])return (<div>{data}</div>)
}

看一下这段简单的代码,页面最终展示的数字是几?

1 这样吗?我觉得应该也是这样,可事实就是在 React18 里,这并不是预期效果,最终展示的其实是 2,为什么呢?

useEffect 的"新特性"

根据 React 最新的文档[1] 中对于 useEffect 的介绍得知,之所以我们刚才的例子最终展示的是 2 而不是 1 的原因是,在 dev 环境下,React 会将每个组件挂载两次进行测试。测试什么?测试你的 useEffect 有没有潜在问题

大家都知道函数式组件挂载后,会执行 useEffect 定义的副作用;在组件卸载时,会执行 useEffect return 出来的回调执行一些组件卸载时的行为,即:

function App () {useEffect(() => {console.log('组件挂载了')return () => {console.log('组件卸载了')}}, [])return (<div>useEffect</div>)
}

从组件挂载到卸载就会依次打印:

组件挂载了
组件卸载了

而在 React18 里,是这样打印的:

组件挂载了
组件卸载了
组件挂载了

按照文档里所说的,之所有这么做的,是为了通过挂载两次组件来提早发现你的问题,例如:

import { useEffect, useState } from 'react'function App () {const [data, setData] = useState(0)useEffect(() => {setInterval(() => {setData(preData => preData + 1)}, 1000)}, [])return (<div>{data}</div>)
}

这段代码时很多刚使用 React 的同学经常会犯的错误,在 useEffect 里定义了个定时器,但没有在任何地方去清除它,所以即使在组件卸载了,这个定时器仍然还在运作,不光造成了内存泄漏,还可能会导致程序出现问题

所以就基于这段错误的代码,React18 执行 挂载 => 卸载 => 挂载,你就会发现,实际是有两个定时器在跑的,所以原本你想每秒 data + 1,变成了每秒 data + 2,如此明显的问题一下就被我们发现了

那正确的做法就是在 useEffectreturn 一个用于卸载时执行的回调函数:

import { useEffect, useState } from 'react'function App () {const [data, setData] = useState(0)useEffect(() => {
+   const timer = setInterval(() => {setData(preData => preData + 1)}, 1000)+   return () => clearInterval(timer)}, [])return (<div>{data}</div>)
}

这样就没有问题了。谢谢 React18 这个"独特"的新特性(手动狗头)

单单基于这个出发点,我觉得是非常好的,能帮我们提早发现问题,解决问题,而不是等发到线上后造成了性能问题,回过头来再逐一排查。而且这只会在开发环境才会挂载两次,生产环境还是正常的

但真的是个完美的特性吗?根据网友的吐槽和我目前使用下来的感受,给我们造成的麻烦可能大于它本身的好处了

即使我的 useEffect 里根本没有需要在卸载时清理的对象,它也会被执行两次,比如请求两次、赋值两次 ... 这似乎是给我们造成了不少的负担啊,不知道的以为是别的地方出了 bug 呢!

关闭特性

我也可以手动关闭这个特性,找到入口文件 main.tsx,把 StrictMode 标签给去掉就好了

mport React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import './index.css'ReactDOM.createRoot(document.getElementById('root')!).render(
- <React.StrictMode><App />
- </React.StrictMode>
)

不过这样也把其它的提示给一并干掉了,其实我是不想这么做的

只是这样?

有很多人都在吐槽着!比如:初始化时 useEffect 会造成两次请求的话,似乎我们也不该在 useEffect 中发起请求?

0fc947440653e8c6589270ba9c51895f.png

然而 Dan 给出的解释就是说,你应该在服务端渲染时就请求到数据,而不是在客户端渲染挂载了 DOM 后才请求数据

其实 React18 将在之后推出一些别的功能,这个模拟组件重新挂载的特性只是为之后的功能做准备的,具体是什么功能呢?类似于 Vue 的 KeepAlive[2]

最后

简单总结一下:这个特性出发点是好的,同时也是为了之后的新特性做准备。但推出这个功能的同时也要考虑一下开发者的体验(起码是大部人的开发体验),不然真的是得不偿失。

对于 useEffect 这个新特性,你怎么看?欢迎在评论区留言!

参考资料

[1]

React 最新的文档: https://beta-reactjs-org-git-effects-fbopensource.vercel.app/learn/synchronizing-with-effects

[2]

KeepAlive: https://vuejs.org/guide/built-ins/keep-alive.html#basic-usage

c8916728a53356a17cfc2e38b0ec9c90.gif

往期推荐

协程到底有什么用?6种I/O模式告诉你!

快速入门 Docker 的五种网络模式

Redis 内存满了怎么办?这样置才正确!

Kubernetes 弃用 Docker ,我们该怎么办?

0cde75a732b6684b722455b29bf34fc8.gif

点分享

ce640eb59119dc05523e76d222d24676.gif

点收藏

4914b10bcb09471971a1a83a103fedc9.gif

点点赞

0a2ff9b9f01cc49ca70974d5b5f3d775.gif

点在看

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/511685.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何构建一个流量无损的在线应用架构 | 专题中篇

简介&#xff1a;本篇是整个《如何流量无损的在线应用架构》系列的第二篇&#xff0c;这一系列共三篇&#xff0c;旨在使用最为朴素的语言将影响在线应用流量稳定性的技术问题做一个归类&#xff0c;这些问题的解决方案有的只是一些代码层面的细节&#xff0c;有的需要工具进行…

一文读懂蓝绿发布、A/B 测试和金丝雀发布的优缺点

简介&#xff1a;目前&#xff0c;业界已经总结出了几种常见的服务发布策略来解决版本升级过程中带来的流量有损问题。本文首先会对这些普遍的发布策略进行简单的原理解析&#xff0c;最后结合阿里云的云原生网关对这些发布策略进行实践。 作者 | 扬少 背景 目前&#xff0c…

Kafka 到底有多高可靠?

作者 | 敖丙来源 | 敖丙什么叫可靠性&#xff1f;大家都知道&#xff0c;系统架构有三高&#xff1a;「高性能、高并发和高可用」&#xff0c;三者的重要性不言而喻。对于任意系统&#xff0c;想要同时满足三高都是一件非常困难的事情&#xff0c;大型业务系统或者传统中间件都…

阿里云张振尧:阿里云边缘云驱动5G时代行业新价值

简介&#xff1a;近日&#xff0c;以“5G融合通信趋势下的技术创新”为主题的2021中国增值电信及虚拟运营高峰论坛在北京召开&#xff0c;阿里云边缘云高级产品专家张振尧发表了《阿里云边缘云驱动5G时代行业新价值》主题演讲&#xff0c;分享了阿里云边缘云作为5G时代的新基础…

美的工业技术亮相2022汉诺威工业博览会,助力全球工业向数字化与可持续迈进

2022年5月31日&#xff0c;2022汉诺威工业博览会开幕并重启线下展览&#xff0c;美的工业技术以“科技驱动&#xff0c;拥抱高效、绿色、智能的工业未来”为主题&#xff0c;携旗下工业自动化品牌“高创”、 “合康新能”和“东菱”&#xff0c;以覆盖自动化、绿色能源领域的领…

hyengine - 面向移动端的高性能通用编译/解释引擎

简介&#xff1a;手机淘宝客户端在历史上接过多种多样的脚本引擎&#xff0c;用于支持的语言包括&#xff1a;js/python/wasm/lua&#xff0c;其中js引擎接过的就有&#xff1a;javascriptcore/duktape/v8/quickjs 等多个。众多的引擎会面临共同面临包大小及性能相关的问题&…

如何进行基于Anolis OS的企业级Java应用规模化实践?|龙蜥技术

简介&#xff1a;提供了724小时的专属钉钉或者电话支持&#xff0c;响应时间保证到在业务不可用情况下10分钟响应&#xff0c;业务一般的问题在一小时可以获得响应&#xff0c;主要城市可以两小时内得到到达现场的服务。 本文作者郁磊&#xff0c;是Java语言与虚拟机SIG负责人…

大数据的下一站 DataOps,智领云发布纯 K8s 云原生数据平台 BDOS Online

最近几年&#xff0c;业界对数据中台的追捧度像坐过山车从高点走低&#xff0c;但在数字化和业务创新驱动下&#xff0c;对数据管理与分析的热度在今年不降反升。 以往搭建一套 Hadoop 大数据平台&#xff0c;技术团队重点要搞定数据的采集、存储、处理和数仓的设计搭建等复杂动…

“全”事件触发:阿里云函数计算与事件总线产品完成全面深度集成

简介&#xff1a;目前&#xff0c;函数计算已具备接入EventBridge所有事件源的触发能力&#xff0c;实现触达阿里云全系产品服务的“最后一公里”。 作者&#xff1a;史明伟&#xff08;世如&#xff09;阿里云高级技术专家 随着云原生技术的普及和落地&#xff0c;企业在构建…

开源 Serverless 里程碑:Knative 1.0 来了

简介&#xff1a;近期Knative发布了1.0版本&#xff0c;达到了一个重要的里程碑。Knative自2018年7月首次发布以来, 版本不断的迭代发展&#xff0c;除了无数的错误修复、稳定性和性能增强之外&#xff0c;按时间顺序还进行了一些改进&#xff0c;下文将进行简单介绍。 作者&a…

勒索软件攻击层出不穷,企业如何做好数据保护?

近日&#xff0c;“搜狐员工遭遇工资补助诈骗”事件引起广泛热议&#xff1a;搜狐员工收到一封来自“搜狐财务部”名为《5月份员工工资补助通知》的邮件&#xff0c;员工按照邮件要求扫码&#xff0c;填写银行账号等信息后&#xff0c;大家并没有等到“补助”&#xff0c;并且工…

以一致的体验交付和管理云原生多集群应用

简介&#xff1a;本次文章将首先介绍云原生应用交付和管理的挑战&#xff0c;然后介绍这背后的 KubeVela 和 OCM 技术原理&#xff0c;最后是整体的最佳实践&#xff0c;以及一个完整的 Demo。 作者&#xff1a;冯泳&#xff0c;孙健波 大家好&#xff0c;很高兴能在 KubeCon…

阿里云低代码音视频工厂正式上线,为企业用户提供音视频开发最短路径

简介&#xff1a;阿里云低代码音视频工厂正式上线&#xff0c;极大程度降低音视频开发门槛&#xff0c;打破传统音视频开发壁垒&#xff0c;全新定义音视频应用开发。 1月5日&#xff0c;阿里云低代码音视频工厂正式上线&#xff0c;极大程度降低音视频开发门槛&#xff0c;打…

网络的现代化建设如何进行?详解 Aruba 平台重要特性

作者 | 宋慧 出品 | CSDN 云计算 5G 和 IoT 的快速发展&#xff0c;以及新商业环境的挑战下&#xff0c;网络也在进入新的发展阶段。 商业竞争变化&#xff0c;企业纷纷采取数字化转型以提升创新性和效率。另外&#xff0c;疫情之后&#xff0c;混合办公模式的普及和常态化后&…

阿里云刘强:无影云电脑构建云上安全办公室

简介&#xff1a;无影云电脑提供触手可及的算力&#xff0c;在云办公、外企办公、分支机构办公、软件开发、人力外包等场景构建云上安全办公室。 2021年12月21日&#xff0c;阿里云弹性计算年度峰会在上海正式举行&#xff0c;并通过全实景进行直播。峰会上&#xff0c;阿里云…

掘地三尺搞定 Redis 与 MySQL 数据一致性问题

‍作者 | 就是码哥呀来源 | 码哥字节Redis 拥有高性能的数据读写功能&#xff0c;被我们广泛用在缓存场景&#xff0c;一是能提高业务系统的性能&#xff0c;二是为数据库抵挡了高并发的流量请求。把 Redis 作为缓存组件&#xff0c;需要防止出现以下的一些问题&#xff0c;否则…

如何在golang代码里面解析容器镜像

简介&#xff1a;容器镜像在我们日常的开发工作中占据着极其重要的位置。通常情况下我们是将应用程序打包到容器镜像并上传到镜像仓库中&#xff0c;在生产环境将其拉取下来。然后用 docker/containerd 等容器运行时将镜像启动&#xff0c;开始执行应用。但是对于一些运维平台来…

Alibaba Cloud Toolkit 中SLS插件助力线上服务问题排查

简介&#xff1a;Alibaba Cloud Toolkit 是一款非常优秀的插件&#xff0c;新增SLS日志服务的功能&#xff0c;针对软件开发者日常工作中常见的问题排查场景&#xff0c;将日志服务平台的功能集成到ide当中&#xff0c;省去了不同窗口之间来回切换的时间&#xff0c;大大提高了…

别等被偷家了,再说数据安全~

在数字经济和技术生态高质量发展的今天&#xff0c;企业对前沿技术和高质量人才的需求不断升级。为了帮助更多开发者、企业洞察行业趋势、技术热点&#xff0c;CSDN 重磅打造技术访谈金牌栏目《架构师说》&#xff0c;聚焦数字化转型、云原生、数据库、开源技术、人工智能、出海…

iLogtail使用入门-K8S环境日志采集到SLS

​简介&#xff1a;iLogtail是阿里云中简单日志服务又名“SLS”的采集部分。 它用于收集遥测数据&#xff0c;例如日志、跟踪和指标&#xff0c;目前已经正式开源(https://github.com/alibaba/ilogtail)。本文通过介绍ilogtail如何在K8S环境进行安装、配置、使用的最简流程&…