React新文档切记不要滥用effect

目录
  • 引言
  • 一些理论知识
    • 处理副作用
  • 总结

引言

你或你的同事在使用useEffect时有没有发生过以下场景:

当你希望状态a变化后发起请求,于是你使用了useEffect

useEffect(() => {
  fetch(xxx);
}, [a])

这段代码运行符合预期,上线后也没问题。

随着需求不断迭代,其他地方也会修改状态a。但是在那个需求中,并不需要状态a改变后发起请求。

你不想动之前的代码,又得修复这个bug,于是你增加了判断条件:

useEffect(() => {
  if (xxxx) {
    fetch(xxx);
  }
}, [a])

某一天,需求又变化了!现在请求还需要b字段。

这很简单,你顺手就将b作为useEffect的依赖加了进去:

useEffect(() => {
  if (xxxx) {
    fetch(xxx);
  }
}, [a, b])

随着时间推移,你逐渐发现:

  • 是否发送请求与if条件相关
  • 是否发送请求还与a、b等依赖项相关
  • a、b等依赖项又与很多需求相关

根本分不清到底什么时候会发送请求,真是头大...

如果以上场景似曾相识,那么React新文档里已经明确提供了解决办法。

一些理论知识

新文档中这一节名为Synchronizing with Effects,当前还处于草稿状态。

但是其中提到的一些概念,所有React开发者都应该清楚。

首先,effect这一节隶属于Escape Hatches(逃生舱)这一章。

从命名就能看出,开发者并不一定需要使用effect,这仅仅是特殊情况下的逃生舱。

React中有两个重要的概念:

Rendering code(渲染代码)

Event handlers(事件处理器)

Rendering code指开发者编写的组件渲染逻辑,最终会返回一段JSX

比如,如下组件内部就是Rendering code

function App() {
  const [name, update] = useState('KaSong');
  return <div>Hello {name}</div>;
}

Rendering code的特点是:他应该是不带副作用的纯函数。

如下Rendering code包含副作用(count变化),就是不推荐的写法:

let count = 0;
function App() {
  count++;
  const [name, update] = useState('KaSong');
  return <div>Hello {name}</div>;
}

处理副作用

Event handlers是组件内部包含的函数,用于执行用户操作,可以包含副作用

下面这些操作都属于Event handlers

  • 更新input输入框
  • 提交表单
  • 导航到其他页面

如下例子中组件内部的changeName方法就属于Event handlers

function App() {
  const [name, update] = useState('KaSong');
  const changeName = () => {
    update('KaKaSong');
  }
  return <div onClick={changeName}>Hello {name}</div>;
}

但是,并不是所有副作用都能在Event handlers中解决。

比如,在一个聊天室中,发送消息是用户触发的,应该交给Event handlers处理。

除此之外,聊天室需要随时保持和服务端的长连接,保持长连接的行为属于副作用,但并不是用户行为触发的。

对于这种:在视图渲染后触发的副作用,就属于effect,应该交给useEffect处理。

回到开篇的例子:

当你希望状态a变化后发起请求,首先应该明确,你的需求是:

状态a变化,接下来需要发起请求

还是

某个用户行为需要发起请求,请求依赖状态a作为参数?

如果是后者,这是用户行为触发的副作用,那么相关逻辑应该放在Event handlers中。

假设之前的代码逻辑是:

  • 点击按钮,触发状态a变化
  • useEffect执行,发送请求

应该修改为:

  • 点击按钮,在事件回调中获取状态a的值
  • 在事件回调中发送请求

经过这样修改,状态a变化与发送请求之间不再有因果关系,后续对状态a的修改不会再有无意间触发请求的顾虑。

总结

当我们编写组件时,应该尽量将组件编写为纯函数。

对于组件中的副作用,首先应该明确:

是用户行为触发的还是视图渲染后主动触发的?

对于前者,将逻辑放在Event handlers中处理。

对于后者,使用useEffect处理。

这也是为什么useEffect所在章节在新文档中叫做Escape Hatches —— 大部分情况下,你不会用到useEffect,这只是其他情况都不适应时的逃生舱。

以上就是React新文档切记不要滥用effect的详细内容,更多关于React文档effect的资料请关注我们其它相关文章!

(0)

相关推荐

  • vue3+ts中ref与reactive指定类型实现示例

    目录 ref 的基础特性 如何在ref中指定类型 reactive isRef.isReactive toRef.toRefs.toRaw ref 的基础特性 ref 约等于 reactive({ value: x }) ref() 可以定义时无参数,第一次赋值任意类型,然后就不能增加属性 const refa = ref(6) const rcta = reactive({ value: 12 }) console.log('refa:', refa) //RefImpl{...} conso

  • Rust+React创建富文本编辑器

    目录 简介 数据模型 核心逻辑 视图 手动差异化 杂项 总结 简介 在Fiberplane,我们最近遇到了一个有趣的挑战:我们正在使用的富文本编辑器库已经过时了.我们曾经使用Slate.js——一个很好的编辑器——但是当我们为协作编辑实现我们自己的富文本基元时,我们发现我们自己的基元和Slate的数据模型之间的脱节是一个阻碍因素.所以我们开始思考——如果我们建立自己的富文本编辑器(RTE, Rich Text Editor)会怎样? 从一个非常高层次的角度来看,一个富文本编辑器是由两个部分组成的

  • Vite + React从零开始搭建一个开源组件库

    目录 前言 目标 搭建开发环境

  • React Native中实现动态导入的示例代码

    目录 背景 多业务包 动态导入 Metro 打包原理 打包过程 bundle 分析 __d函数 __r函数 方案设计 分 识别入口 树拆分 bundle 生成 合 总结 背景 随着业务的发展,每一个 React Native 应用的代码数量都在不断增加,bundle 体积不断膨胀,对应用性能的负面影响愈发明显.虽然我们可以通过 React Native 官方工具 Metro 进行拆包处理,拆分为一个基础包和一个业务包进行一定程度上的优化,但对日益增长的业务代码也无能为力,我们迫切地需要一套方案来

  • C++中的Reactor原理与实现

    目录 一.Reactor介绍 二.代码实现 一.Reactor介绍 reactor设计模式是event-driven architecture的一种实现方式,处理多个客户端并发的向服务端请求服务的场景.每种服务在服务端可能由多个方法组成.reactor会解耦并发请求的服务并分发给对应的事件处理器来处理. 中心思想是将所有要处理的I/o事件注册到一个中心I/o多路复用器上,同时主线程/进程阻塞在多路复用器上;一旦有I/o事件到来或是准备就绪(文件描述符或socket可读.写),多路复用器返回并将事

  • React新文档切记不要滥用effect

    目录 引言 一些理论知识 处理副作用 总结 引言 你或你的同事在使用useEffect时有没有发生过以下场景: 当你希望状态a变化后发起请求,于是你使用了useEffect: useEffect(() => { fetch(xxx); }, [a]) 这段代码运行符合预期,上线后也没问题. 随着需求不断迭代,其他地方也会修改状态a.但是在那个需求中,并不需要状态a改变后发起请求. 你不想动之前的代码,又得修复这个bug,于是你增加了判断条件: useEffect(() => { if (xxx

  • React新文档切记不要滥用Ref

    目录 引言 为什么是逃生舱? 失控的Ref 如何限制失控 人为取消限制 useImperativeHandle 总结 引言 React新文档有个很有意思的细节:useRef.useEffect这两个API的介绍,在文档中所在的章节叫Escape Hatches(逃生舱). 显然,正常航行时是不需要逃生舱的,只有在遇到危险时会用到. 如果开发者过多依赖这两个API,可能是误用. 在React新文档:不要滥用effect哦中我们谈到useEffect的正确使用场景. 今天,我们来聊聊Ref的使用场景

  • 给XML文档添加新 ”records”

    本文所举的例子与保存HTML格式数据至XML类似.在以往当表格被提交后,我们通常会创建一个新的文档,现在只要文档已经存在,那么直接添加就可以了.此种技术的使用与创建基本数据类似. 在前面的文章里,我已经演示了如何使用XMLDOM.因此,我们可以直接进入本文的示例. 我们需要考虑的第一件事是我们将用于添加新"记录"的HTML 表单.在"将HTML表单数据保存至XML"例子中我们已使用过此表单,只是更改了文件名,但代码是相同的. AddContact.html: 复制代

  • html文档中的location对象属性理解及常见的用法

    关于location对象的简单理解: 1.location对象中涵盖了当前页面(本页面)或者更直接的说,是当前加载的这个html文档的url信息 2.location对象作为window对象的一个属性,可以通过window.location老访问 下面顺便介绍一些URL(资源定位符)的相关信息吧: 在浏览器中URL通常由下面几个部分组成的: [协议][host][path][query] 协议:常见的协议有: http:// 表示资源文件在web服务器上 ftp://表示资源文件在网络上的ftp

  • asp.net 在线编辑word文档 可保存到服务器

    注意:你要打开的服务器端的word文档要有写权限.iis要开起 web服务扩展中的webdav为允许 具体参考文档msdn:http://msdn2.microsoft.com/en-us/library/ms454230.aspx 原理:通过 javascript 创建一个ActiveX控件实例(为浏览者机器Program Files\Microsoft Office\OFFICE11\owssupp.dll或Program Files\Microsoft Office\OFFICE10\ow

  • 从ASP.NET得到Microsoft Word文档的代码

    背景 自动化(Automation)是一个过程,它允许编程语言譬如Visual Basic.NET或C#写的应用程序可以编程控制其它应用程序.自动化到Word允许你执行像创建新文档,向文档中添加文本,邮件合并,还有控制文档格式这样的操作.使用Word和其它Microsoft Office应用程序,几乎所有你能在用户面板上手动实现的操作都可以通过自动化编程实现.Word通过一个对象模型来实现这个编程功能性(programmatically functionality).对象模型是一系列类和方法,它

  • 在PHP中读取和写入WORD文档的代码

    复制代码 代码如下: <?  // 建立一个指向新COM组件的索引  $word = new COM("word.application") or die("Can't start Word!");  // 显示目前正在使用的Word的版本号  //echo "Loading Word, v. {$word->Version}<br>";  // 把它的可见性设置为0(假),如果要使它在最前端打开,使用1(真)  // t

  • C#实现通过模板自动创建Word文档的方法

    本文实例讲述了C#实现通过模板自动创建Word文档的方法,是非常实用的技巧.分享给大家供大家参考.具体实现方法如下: 引言:前段时间有项目要用c#生成Word格式的计算报告,通过网络查找到很多内容,但是都很凌乱,于是自己决定将具体的步骤总结整理出来,以便于更好的交流和以后相似问题可以迅速的解决! 现通过具体的示例演示具体的步骤:   第一步,制作模板   1.新建一个文档,设置文档内容. 2.在相应位置插入书签:将鼠标定位到要插入书签的位置,点击"插入">"书签&quo

  • Java经验点滴:类注释文档编写方法

    文章来源:csdn 作者:chensheng913 对于Java语言,最体贴的一项设计就是它并没有打算让人们为了写程序而写程序--人们也需要考虑程序的文档化问题.对于程序的文档化,最大的问题莫过于对文档的维护.若文档与代码分离,那么每次改变代码后都要改变文档,这无疑会变成相当麻烦的一件事情. 解决的方法看起来似乎很简单:将代码同文档"链接"起来.为达到这个目的,最简单的方法是将所有内容都置于同一个文件.然而,为使一切都整齐划一,还必须使用一种特殊的注释语法,以便标记出特殊的文档:另外还

  • 如何在Web页面上直接打开、编辑、创建Office文档

    如何在Web页面上直接打开.编辑.创建Office文档  有朋友询问如何在Web页面上做到像SharePoint中的效果一样,能直接激活客户端的Word来打开.doc文件,而不是类似直接点击.doc文档链接时Word在IE中被打开那样.想想这个问题应该很多人都会感兴趣,所以干脆写一篇blog来大致描述一下方法. 在安装Office2003以后,有一个ActiveX控件被安装到了系统中,这个控件位于"Program Files\Microsoft Office\OFFICE11\owssupp.d

随机推荐