如何让 useEffect 只在依赖变化的时候执行

遇到问题 今天遇到一个 useEffect 的问题,遇到一个问题:在 useEffect 里面发异步请求,然后第二个参数的依赖也是异步请求之后得到的结果,然后就导致最终结果会请求两次 useEffect 里的函数。 const [metaKey, setMetaKey] = useState<string[]>([]) // useEffect1 useEffect(() => { getServiceCoreIndexParam().then((res: IResult) => { setMetaKey(res.data.defaultValue) return res.data }) }, []) // useEffect2 useEffect(() => { getAdvisorIndexTable({ visitdate: props.visitdate, advisorSupervisor: props.advisorSupervisor, comparevisitdate: props.comparevisitdate, metaKeys: metaKey || [] }).then((res: IResult) => { res.success && setTable(res.data) }) }, [props.visitdate, props.advisorSupervisor, metaKey, props.comparevisitdate]) 分析一下这段代码,首先在组件 mount 的时候,useEffect2 会调用一次 getAdvisorIndexTable,当 useEffect1 执行完毕之后 setMetaKey 后,由于 metaKey 发生改变,导致 getAdvisorIndexTable 还会调用一次,这很明显是我们不想看到的结果,因为这只是一个默认请求,然而发了两次请求。...

October 14, 2019 · 2 min · 266 words · 桃翁

新手学习 React 迷惑的点

网上各种言论说 React 上手比 Vue 难,可能难就难不能深刻理解 JSX,或者对 ES6 的一些特性理解得不够深刻,导致觉得有些点难以理解,然后说 React 比较难上手,还反人类啥的,所以我打算写两篇文章来讲新手学习 React 的时候容易迷惑的点写出来,如果你还以其他的对于学习 React 很迷惑的点,可以在留言区里给我留言。 为什么要引入 React 在写 React 的时候,你可能会写类似这样的代码: import React from 'react' function A() { // ...other code return <h1>前端桃园</h1> } 你肯定疑惑过,下面的代码都没有用到 React,为什么要引入 React 呢? 如果你把 import React from ‘react’ 删掉,还会报下面这样的错误: 那么究竟是哪里用到了这个 React,导致我们引入 React 会报错呢,不懂这个原因,那么就是 JSX 没有搞得太明白。 你可以讲上面的代码(忽略导入语句)放到在线 babel 里进行转化一下,发现 babel 会把上面的代码转化成: function A() { // ...other code return React.createElement("h1", null, "前端桃园"); } 因为从本质上讲,JSX 只是为 React.createElement(component, props, ...children) 函数提供的语法糖。...

September 5, 2019 · 5 min · 1019 words · 桃翁

Deep In React 之详谈 React 16 Diff 策略(二)

文章首发于个人博客 这是我 Deep In React 系列的第二篇文章,如果还没有读过的强烈建议你先读第一篇:详谈 React Fiber 架构(1)。 前言 我相信在看这篇文章的读者一般都已经了解过 React 16 以前的 Diff 算法了,这个算法也算是 React 跨时代或者说最有影响力的一点了,使 React 在保持了可维护性的基础上性能大大的提高,但 Diff 过程不仅不是免费的,而且对性能影响很大,有时候更新页面的时候往往 Diff 所花的时间 js 运行时间比 Rendering 和 Painting 花费更多的时间,所以我一直传达的观念是 React 或者说框架的意义是为了提高代码的可维护性,而不是为了提高性能的,现在所做的提升性能的操作,只是在可维护性的基础上对性能的优化。具体可以参考我公众号以前发的这两篇文章: 别再说虚拟 DOM 快了,要被打脸的 深入理解虚拟 DOM,它真的不快 如果你对标题不满意,请把文章看完,至少也得把文章最后的结论好好看下 在上一篇将 React Fiber 架构中,已经说到过,React 现在将整体的数据结构从树改为了链表结构。所以相应的 Diff 算法也得改变,以为以前的 Diff 算法就是基于树的。 老的 Diff 算法提出了三个策略来保证整体界面构建的性能,具体是: Web UI 中 DOM 节点跨层级的移动操作特别少,可以忽略不计。 拥有相同类的两个组件将会生成相似的树形结构,拥有不同类的两个组件将会生成不同的树形结构。 对于同一层级的一组子节点,它们可以通过唯一 id 进行区分。 基于以上三个前提策略,React 分别对 tree diff、component diff 以及 element diff 进行算法优化。 具体老的算法可以见这篇文章:React 源码剖析系列 - 不可思议的 react diff...

July 30, 2019 · 6 min · 1235 words · 桃翁

发布 react 组件到 npm 上

我发布了我的第一个 npm 组件,一个基于 react 的 3d 标签云组件。在这途中我也是遇到了很多的坑,花在完善整个发布流程的时间远多于写这个组件本身的时间,所以我记录下我觉得一个正常的 react 组件的发布流程 最后记录这篇文章花的时间比我完成整个组件的时间都多,最终希望能给新手带来帮助 在整个发布组件的过程我做了如下几件事儿: 开发组件 编写 Readme 推送到 github,并且把 demo 放到 github page 上 发布组件到 npm 上 开发组件 创建项目文件夹并初始化 npm package ,确保你创建的组件名称没有在 npm 上被使用过, 这里我们用 react-demo 作为示例 mkdir react-demo cd react-demo npm init npm init 是生成初始的 package.json 的命令,在 npm init 的时候,你可以根据你自己的需要进行填写你的组件信息。或者直接使用 npm init -y 采用默认的,后面自己再去修改。 首先安装 react 相关的包: npm i react react-dom -D 采用 babel 编译相关的依赖: npm i @babel/cli @babel/core @babel/preset-env @babel/preset-react -D 采用 webpack 做构建,webpack-dev-server 作为本地开发服务器,所以需要安装如下依赖:...

January 28, 2019 · 5 min · 952 words · 桃翁

不要再说虚拟 DOM 有多快了

如果你觉得它很快,那么这篇文章可能就是你所缺少的 我经常听到有人在群里,或者在社区里说的一个很严重的错误,那就是说 React 的 Virtual Dom 是以快出名的,比原生 Dom 快多了,啥啥啥的,每次都一两句话说不清楚,所以下次有谁再说 React 是以快出名的,你就把这篇文章丢给他,下面进入正题。 在过去的几年里,你一直在跟踪 JavaScript 社区的发展,你至少听说过 Virtual DOM(React,Vue.js 2,Riot.js,Angular 2等等)。他们承诺(或者更确切地说,他们的宣传)更快的渲染界面,特别是更新,减少麻烦。你很快的上手了使用虚拟DOM的应用程序,这很好。几个月后,您的应用程序现在变得越来越复杂,你可能从用户交互到屏幕更新只需要一两秒钟的更新。你可能会想,这东西很神奇,应该会比 jQuery 快,但是实际上不是这个样子的。 虽然我同意虚拟 DOM 为我们提供了很多便利,但我将解释为什么我认为根据定义,更快的渲染和更快的更新是不正确的。要付出代价,其利益并不是大多数人想象或至少希望的。 要阅读本文,您需要熟悉DOM。理想情况下,您至少可以使用 DOM API。如果你只使用 DOM API 构建东西,你可能不需要这篇文章,但我仍然希望你阅读它并在评论中留下一点评语。 渲染和更新 让我们来看看手动执行 DOM 节点的创建和更新的鸟瞰图。这对于理解虚拟DOM如何工作以及它解决了哪些问题非常重要。 在谈论 JavaScript Web 应用程序时,用户界面的更改通过 DOM 操作发生。这个过程分为两个阶段: JS 部分:定义 JavaScript 世界中的变化 DOM 部分:使用 DOM API 函数和属性执行更改 性能是根据整个过程的速度来衡量的,但了解每部分的速度也很重要,以便了解要优化的内容。 有两种方法可以创建和更新DOM树的各个部分。 ①字符串方式创建 使用字符串既快速又简单,但在更新方面并不是非常精细。对于字符串,JS部分是它如此之快的原因。您可以在几毫秒内创建一段代表5000个节点的HTML。这是一个例子: const userList = document.getElementById("user-list"); // JS 部分 const html = users.map(function (user) { return ` <div id="${user.id}" class=”user”> <h2 class="header">${user....

November 20, 2018 · 2 min · 352 words · 桃翁