React是什么?
是用于JavaScript库,换句话来说,React是一个开源JavaScript库。
React是谁开发的?
由公司开发,且开源。【2013年5月宣布开源】近十年沉淀,现被大厂广泛使用。
React的特点
- 采用模式、编码,提高开发效率及组件复用率。
- 在中可以使用语法进行移动端开发。
- 使用+优秀的算法,尽量减少与真实DOM的交互。
- 速度快(UI渲染中,React通过虚拟DOM与真实DOM的比较,直接避免了不必要的真实DOM操作)
- 跨浏览器兼容、兼容性好(requireJS加载&打包),...
[ 运行这段JavaScript实现的代码之后,有两个人的数据,分别为张三、李四。如果我想再往这上面再添加一个王五,JS不会复用页面已有的张三、李四这两条数据,而是3个DOM,等于说前两个没必要重新渲染,但还是被渲染了,一旦数据量大,性能方面就有问题了。]
- 如果往100个人的后面新增一个人,前面100个人都没变,但最终渲染时,会重新生成101个DOM,你会觉得性能浪费吗?1000个人呢?10000个呢?
上面的例子:100个人,第一次React会生成100个虚拟DOM通过比较,没有,则生成100个真实DOM;第二次追加一个人,React会进行虚拟DOM的比较,发现前面的100个React都有,那么最终只生成1个真实DOM。而不是像原生JS一样,追加一条数据,会全部重新渲染,又生成101个真实DOM,不能复用。这就是React的优点之一。
React与Vue的区别
1. Vue运行更快,学习也更快,唯一的缺点,Vue用久了之后,会发现自己的js基础代码不会写了。
2. ,提供了很多第三方的库供React开发人员去选择(像React的路由、状态管理库等都可以根据需要去选择;而Vue灵活性就会稍微差点,(Vue-Router、Vuex,Pinia))
3. Vue是响应式的,而React是手动setState(更新状态的)。
4. React也好上手但是难于写出优美的代码,对JS的要求更高。
5. 任何希望构建并有可能在未来通过更多开发人员的人,React 可能是首选。然而,Vue 是开发的最佳选择。
学习React之前你要掌握的JavaScript基础知识
- 判断this的指向
- class(类)
- ES6语法规范
- 包管理器(npm,yarn等)
- 原型、原型链
- 数组常用方法
- 模块化
React脚手架
- xxx脚手架:用来帮助程序员一个基于xxx库的模板项目。
- (1)包含了所有需要的配置(语法检查、jsx编译、devServer...)
- (2)下载好了所有相关的依赖
- (3)可以直接运行一个简单的效果
- React提供了一个用于创建React项目的脚手架库:
- 项目的整体技术架构为:react + webpack + es6 + eslint
- 使用脚手架开发的项目的特点:模块化、组件化、工程化
创建项目并启动
- 第一步,全局安装:
- 第二步,切换到想创项目的目录,使用命令: 项目名
- 第三步,进入项目文件夹: 项目名
- 第四步,启动项目:,看package.json文件具体命令
前言(扯皮-可以不用知道)
- React的特点之一就是,JSX是JavaScript的,使用JSX来UI内容。React开发使用JSX,但使用JSX会非常便捷。
- 实际上是函数的,使用JSX需要使用来将JSX转化成createElement函数调用(React 16版本)。
3. 提供了一个的 的版本。jsx语法不再化为createElement函数,而是内部通过中生成虚拟对象。
在如果引入React仅为了存在你就可以从组件代码中React的导入。
React 17编译器从导入了一个新的依赖项,它处理。
什么是JSX?
- 是的一种,运用于架构中,其格式像模板语言,但事实上完全是在JavaScript内部实现的。
React为什么推荐使用JSX?
:ReactJSX,但大多数人发现,在JavaScript代码中将JSX和UI放在一起时,会在视觉上有辅助作用。它还可以使React显示更多有用的错误和警告信息。
:JSX语法糖允许前端开发者使用我们最熟悉的来,在降低学习成本的同时,也提升了研发效率与研发体验。
JSX的使用
使用JSX创建React元素
在JSX中嵌入表达式
JSX条件渲染
JSX特定属性
JSX中绑定事件
setState
(3种方式)
在类组件中,通过改变状态后立马获取该状态、获取到的值是上一次的。
所以说,更新状态时不要在作用域内试图拿该状态去处理数据,容易出bug。
1.1:state理解
- (React 状态)是组件对象最重要的属性,值是对象(可包含多个key-value的组合)
- React把组件看成是一个状态机(),通过更新组件的来更新对应的页面显示(重新渲染组件)
1.2:需要注意
- 类式组件中中的this为组件实例对象
- 类式组件的方法中,为什么?如何解决?
- 根据的语法规则,所有在类中定义的方法都默认开启。在严格模式下,所有window对象的this,都全部变更为。
- a):通过在render中通过bind绑定this
- b): func = () => {},通过作用域链查找获取this指向
- 状态数据,不能直接修改或更新
组件,从概念上类似于JavaScript函数。它接受任意的入参(即),并返回用于描述页面展示内容的React元素。
组合组件
Props的只读性
`组件无论是使用函数声明还是通过class声明,都决不能修改自身的props。
开发中遇到的问题
开发中调用接口,async-await搭配使用,【await】需要等到数据拿到再进行后续操作,在调用接口之后通过this.setState({})改变状态()再传递给子组件,子组件拿不到最新的props。
简介:
1. 用于或,(函数组件没有实例,这里指的是类组件)
创建方式:
① 字符串式声明ref
打印结果:
将打印结果展开:
获取该input框的值:this.refs.inputRef1.value
同时,可以使用DOM上的API,比如:
当然,这种字符串声明ref的方式已不再被推荐使用,将来可能会被废弃。
② 用回调的方式创建ref(推荐写法)
③ createRef - 类组件
creatRef-函数组件
效果和上面是一样的
④ 若将ref绑定在类组件上,是什么情况?
效果:
⑤ 函数组件没有实例,但如果将ref绑定在函数组件上,可以吗?会是什么情况?
取到的是报错:
翻译报错信息:
解决:
报错信息告诉我们,不能在函数组件上绑定ref,如果实在要绑定,也行,需要借助forwardRef的力量。
打印结果:
效果:
Redux 理解
Redux官方文档
1. 英文文档: redux.js.org/
2. 中文文档: www.redux.org.cn/
- Github: github.com/reactjs/red…
Redux是什么?
- Redux是一个专门用于做的JS库(不是react插件库)。
- Redux除了和React一起用外,其他界面库。可以用在React、Angular、Vue等项目中,但基本上是与React配合使用。
- 体小精悍(只有2KB,包括依赖)
- 作用:React应用中多个组件的状态
什么情况下需要使用Redux?
- 某个组件的状态,需要让其他组件可以随时拿到(共享)
A、B、C、D都要用到E的某个状态,E只需将需要共享的状态存到Redux中去,需要用到该状态的去Redux中去取就可以了,这也是Redux的作用。
A将状态存到Redux,B要用到A中存的状态,就去Redux中取
Redux原理图
redux提供一个管理state的仓库(),并且规定了存储在store中的状态只能通过(函数)来更新,而reducer必须通过来触发,就是普通的JavaScript对象,它约定了执行的类型并且传递数据。使得是可以预测的,同样的步骤会得到同样的state。
- redux是做集中式状态管理的,其中,store是扛把子,是redux的核心。
- store是管理state的仓库,使用它之前得先创建它。
- 创建store得传入reducer,是什么?是个。
- 作用:接收到(type&data),根据type类型和data数据对状态的处理处理后的数据store中。
- action是什么?
是个一般对象
- 目前创建store的方法由改成,名字变更小问题,源码如下。
可以看到,创建store的代码是137-383行,来看一下创建完store后,里面有什么?
- 存在redux仓库中状态的方法:store.getState()
- 存在redux仓库中状态的方法:store.dispatch(action)
Redux用法

可能有的疑问:
- 父组件传入store,父组件是什么?
- store 从父组件传入 里面的逻辑是什么?
- action 里是怎么写的?
让我们看一下 - 解决第一个疑问
再让我们看一下 - 解决第二个疑问
使用redux必须要先安装依赖,npm i redux 或 yarn add redux
可能有的疑问: 4. reducer是什么?
让我们再看一下里写了什么 - 解决第四个疑问
让我们最后看一下 里写了什么 - 解决第三个问题
1. 使用redux多个组件共享状态;那么你要先有组件,才可以去使用。
- 在组件中,无非两件事,① ②
- 两个API,① ②
- 目前我们缺的:① ②
- 在redux原理图中,可以看到,store站在C位,没有它,redux根本跑不起来。

2. index.jsx中缺少store,我们从中引入store传给需要的子组件。
- 有store,① ② ,这里选择第二种,推荐写法。
3. 引入store,就需要创建
- 安装,从中引入并传入用于创建,并导出store
- 当在调用并传入时,会帮我们去通知进行状态加工。而在创建时传入的目的是:。
- 传入reducer,reducer是什么?
4. 需要reducer,那么就要编写
- 在组件调用时,会帮我们去调,通知干活。
- ’这个js文件‘就是reducer?,就因为文件名是reducer.js?在创建时传入一个函数,这个函数被称为,它接收两个参数 ① 上一次的状态,没有就为undefined ② action对象。
- 当然可以在中直接编写一个函数并传入中,但为了后期可维护性,我们选择引入的方式来创建。
5. 万事具备,只欠东风。传入中的对象
- 哪里能用到action?答:
- 哪里能用到dispatch?答:
- action是什么?答:
- 为什么action仅仅是个Object对象,也要单写个文件,使用时将其引入呢?答:
- 在组件中操作状态时可以以dispatch({...})这种形式存在吗?答:。我的意思是将action用单独一个文件统一管理,再在组件需要action时按需引入会更好。最后将引入的action方法交给dispatch方法。当然,该action方法最终也是返回一个一般对象。
在redux的使用中,会发现当按上面编写完代码时,页面效果没有呈现出来
① redux不是Facebook公司出品,还有一定的小瑕疵,组件通过dispatch更改redux中状态时,控制台打印该状态的值,确实已经更改,但没有引发页面的更新。。
在入口文件中,调用身上的方法,该方法用于监听中状态的改变,当状态改变,则执行回调,也就是手动调用了方法,重新渲染。
- 类式组件 - 只要调用了,不管状态,都会调render。
- 函数式组件 - 通过useState解构出的改变状态,若该状态的值,即使调了setxxx也不会重渲染,若状态发生改变,则调用render。(React通过来判断两个值是否相同,是浅比较)
- 父组件重新渲染会引起子组件的重渲染。
React Redux 理解
简介
- 和是两个团体的作品。公司发现,很多程序员写都喜欢用来做集中式状态管理,本着简化编码的原则,直接官方出品 - 。
- 与,它们的关系是:使用(插件库)可以让你更舒服的在项目中去使用。
React Redux原理图
- 将组件分为。① ②
- 所有UI组件的外侧都要一个容器组件,他们是。
- 在容器组件中和Redux打交道,Redux的API。
- UI组件容器组件来获取① ②。
- 容器组件UI组件的通信通过
React Redux用法
先来看看组件 需要解释的点:
- 能取到中状态操作状态方法的是而不是!!!
- 容器组件的是:从插件库中引入。
- 安装:
- 声明容器组件:
- a和b都是函数,它们的是分别是①获取状态 ②操作状态
- react-redux底层经过处理,能使得。
- 同样,,用于操作状态。
- redux中的状态: state={sum, list}
- 操作状态的方法:dispatch(action)
要想使用Redux,必须要有store,那么,我们先把组件看完把,组件
- nanoid - 每次获取都是全世界唯一的id
- 安装:yarn add nanoid
- 使用:const id = nanoid()
- 剩下的就是获取状态和操作状态
- 再次强调!connect()()创建容器组件
- state => ({ key: value}) 经处理,接收到redux中的,返回一个,该对象的用于通过获取,而则是拿到存储在中的。
- 在Count组件中,第二个参数是,但是我们安装了!!!React Redux官方出品能让我们在更加的舒服!第二个参数一个一般对象,里面是一组一组的。是用于通过获取,而则是!!!
- UI组件中使用this.props.appendInfo({name,age,id:nanoid()})?
- react-redux会触发同时传入action,在这里传入的是。addPerson是个函数,接收一个data一个一般对象(appendInfo括号里的参数传给addPerson这个函数的)
- React Redux内部会帮我们去调,接收dispatch再dispatch(action)
- 现在第二个参数 { actionName1: action1, actioknName2: action2, ... }就可以了。
(文件/代码编写顺序可以按自己习惯调整)需要操作Redux中的状态,就要dispatch(action),看下
Count组件下的action
Person组件下的action
解释:
- UI组件容器组件操作状态的方法来。
- 具体表现为:(如果括号里的是参数,则该参数最终传给action处理函数)
- 在容器组件中,第一个括号里的第二个参数,当你去调用它,this.props.name(),那么React Redux内部会去触发方法。
- 而当调用了,会通知进行状态加工,状态加工完后返回给,UI组件若是需要,则通过容器组件获取状态,UI组件再通过获取,问题来了,呢?呢?
先来看下
Count下的reducer
Person下的reducer
再来看下站在C位的store,
解释:
- 旧版用创建,而新版用创建。
- 因为的使命就是,一个组件对应一个,当有多个组件时,的数量也随之增加,但是只有一个,所以当有多个时,就得去中引入,并将这些集中起来传入中用于创建,当需要某个reducer时,就能通知'这个'进行状态加工。
- 而传入combineReducers的是一个对象,。
- 对象中存放着一组一组的key-value,key代表着:;value则代表着:。
具体使用:
5. import { legacy_createStore, combineReducers } from 'react-redux'可以吗?
react-redux帮我们做出的优化1:
- 在中,我们需要在中调用来监测中状态的变化,当状态变化时,调用重新渲染页面;
- 当我们安装了这个插件库容器组件,容器组件会帮我们中状态的改变,若状态改变则重新渲染页面。图中×掉的部分就不用了。
react-redux帮我们做出的优化2:
1.在纯Redux中,我们需要在父组件App中将store传给子组件Count,因为Count要用到它(store.getState()、store.dispatch(action)),当组件个数逐渐变多时,难道我们也要一个一个的传入store吗?
react-redux帮我们做出了优化,从此引入index.js - 入口文件
- Provider:你整个应用里边但凡要用到,我都能给他,换句话说,App里所有的容器组件都能收到store,只需要写一次即可。
- 容器组件UI组件,Redux。在容器组件中使用Redux相关的API,所以说这个对于容器组件来说是!
简介:
什么是Hook?
- 是React 16.8(版本)的。它让你在不编写class的情况下state其他的React特性。
- 是一些可以让你在里“钩入”及等特性的。
- useState
- useEffect
- useContext
用法:
解释:
- 调用函数会返回一个,以及。
- 在,是。
- setState/setApple函数更新。它接受一个state值组件的一次加入队列。
- 当调用setState/setApple时传入state值,(Object.is(值1,值2)),。
- -> Object.is({a:2}, {a:2}) 结果为,对象的引用、该对象存储在内存中的地址,所以说传入一个,不管里面值,。
- 在,useState返回的第一个值将始终是。
注意:
- useState,也可以是,该参数,。:当初始化值需要通过计算得到,则可以在useState Hook中传入一个函数计算初始值。如下:
代码:
效果:

简介:
可以让你在执行操作。
问题:
- 什么是副作用?
① ② ③
个人观点:
只要知道Effect Hook运行的时机, 剩下的就根据不同的业务场景去选择是否要用它。
提示:
- 如果你熟悉的,你可以把看做,和这三个函数的组合。
- React会你传递的函数(我们称它为””)。
常见用法:
第一种情况:
代码:
效果:
解释:
这种情况下,执行的时机是:
①
②
③
第二种情况:
代码:
效果:
解释:
这种情况下,执行的时机是:
①
第三种情况:
代码:
效果:
解释:
这种情况下,执行的时机是:
①
② (A状态发生改变时)
第四种情况:
代码:
效果:
解释:
这种情况下,执行的时机是:
①
②
第五种情况:
代码:
- 入口文件
效果:
- 这种情况下,执行的时机是:
①
②
③
- useEffect(effect),React会在执行当前effect之前对上一个effect进行清除。
简介:
Context一个每层组件手动添加,就能在进行的方法。
问题:
- 何时使用Context?
Context 是为了那些对于一个而言是“”的数据。换句话说,Context的出现子孙组件爷爷组件的数据而从爷爷组件一层一层靠传递的问题。
个人观点:
- 用于组件通信
- 主要的应用场景:多个不同层级的组件需要访问相同的数据。
Context API
- 创建一个(创建上下文环境)。当React渲染一个(React渲染了一个使用useContext(Context对象)的组件),这个组件会从。
- (这个组件指的是要传递数据的组件<MyContext.Provider value={值}>组件(再嵌套组件)</MyContext.Provider>)(没有匹配到Context对象上的Provider组件),。
- ,具体如上。
- 消费组件:这个Context对象上的包裹着,那么,或与(父子关系等)。 都能以某种方式取到这个‘传递的值’。
- 接收一个属性,里面的值传递给。
- 和的关系是:。
- 可以,里层的会外层的数据。
- 当Provider的value值时,!
- 接收一个(React.createContext的返回值)并返回的当前值。当前context的值上层组件中距离当前组件<MyContext.Provider>的决定。,创建时都会有,当你的组件需要某个提供的,那么一定是!
- 当组件上层<MyContext.Provider>时,(useContext)会,最新传递给MyContext provider的context 。,组件的取值组件上层的MyContext provider的,如果上层的值,是不是组件用于获取值的Hook(useContext)拿到最新的值?
- useContext的参数context对象本身
代码1:
效果1:

代码片段:
- 当组件所处的树中Provider时,其默认值才会生效。
- 将默认值和设置成同类型不同值。
代码2:
效果2:
- useReducer
- useCallback
- useMemo
- useImperativeHandle
- useRef
- useLayoutEffect
- useDebugValue(测试钩子,没用)
- useDeferredValue
- useTransition
- useId(用于服务端渲染,没啥用)
简介:
- 官方提供了状态管理的Hook,① ②
- 。useReducer的工作流程几乎和Redux一致,但它不是Redux!
用法:
- useReducer函数接收三个参数,其中第三个是可选参数
- 第一个参数:reducer,,在dispatch方法中传入action动作对象时触发,用于。
- 第二个参数:initState,,传入useReducer中经过处理返回一个。
- 第三个参数:initFunc,,该函数能接受到初始值 - initState,并将处理过后的初始值返回,
下面,我们用代码来模拟一下
- 使用,传入并返回一个,数组是值,是改变值的方法。
- 因为方法最终被返回,所以一定要在useReducer中声明dispatch。
- 方法传入动作对象才能通知去干活,去进行状态加工,所以的参数是。
- 调用了dispatch方法就是 ① ②。状态都要调用返回的的方法:,因为state hook返回的数组里的更新值的方法会对状态进行(通过Object.is),若则调render,若则不会触发render。
- ,不然它拿什么更新?值从哪里来,靠这个加工状态函数最终返回。
- reducer接收两个参数① ② ,传入后经过reducer处理则返回一个,updateState这个更新后的状态浅比较,若两次值不等则就去更新它。
我们将引入到文件去使用,看是否奏效:
问题:
1. useReducer和useState的区别?
- 个人理解:① ② ③
- 如果说某个state其他的state,就放到Hook里去。
2. 为什么useReducer不是/不能取代Redux?
- 虽然 及其 是 工作方式的一部分,但它 Redux。与它的 紧密耦合,这也它的 。我们 action 对象分派给。而在 中,dispatch 函数将 action 对象 store, 将其分发给。您可以将 Redux ,它接收任何事件(动作)并根据动作的和将它们处理为。
性能优化(提前说明)
- ->
- ->
- ->
简介:
- useCallback接收两个参数:① ② (可选)
- 用于缓存函数,如果useCallback第二个参数,使用该hook就,只要页面发生渲染,该函数还是会,没有达到的效果。
- 如果的第二个参数为,则说明它,它在页面就把该函数下来。之后这个函数也再发生改变。
- 如果的第二个参数且有,那么,页面会把这个函数下来,当依赖项的值则并将该函数到内存中去。
- 通常与一起使用。
- List是被缓存的组件,当memo包裹的组件发生变化,memo会组件。
使用场景:
- 对于需要的场合,如果不使用,只要发生重渲染,就会重新渲染。
- 即使子组件被包裹,当发生渲染,依然也会重新渲染,为什么呢?因为React.memo是通过,比较的变化,当发生变化,则组件再将。因为父组件传给子组件的是,所以当你没有用将此函数缓存起来时,你让父组件发生了渲染,那么父组件就会这个函数,props也发生了改变(重新生成function,引用、地址发生了改变),即子组件。但如果父组件传给子组件的是,且子组件被包裹,那么,只要该值没发生变化,无论怎么重渲染,都发生渲染(变化)!
- 在调用节流、防抖函数时
- 在输入框中,用户停止输入300毫秒后开始请求接口获取数据,就得用到防抖函数
- 父组件的每一次渲染都会重新生成一个函数
- useCallback
代码解释:
效果:
- 改变父组件的状态,引起了不必要的渲染 - ① ②
第一步:将子组件用React.memo包裹,将组件缓存
效果:
问题:
- 将子组件用React.memo缓存,但改变父组件的状态,子组件依然被更新,为什么?
因为
- 传递给子组件的是函数,为什么两次的值会不同,好像没改到函数把!?
因为
- 如何解决?
导致这个问题的主要原因在于:
第二步,将传递给子组件的函数缓存下来
效果:
小栗子:
优化前:
代码:
问题:
问题描述:
问题原因:① ②
最终目的:
问题解决: ① ②
优化后:
简介:
从源码中可以看出,
- useMemo hook用于性能优化,功能是缓存值
- useMemo与useCallback可以互相转换(如下图),但不推荐,最好将这两个hook给区分开来。
用法:
- 根据第二个参数来决定第一个参数第一个参数所返回的值,最终将缓存的值赋值给cacheValue。
- 和都是用于,但不能滥用,,用于缓存值的,这个值可以是任意的。而缓存函数的。虽然可以转换,但还是希望。
- 若没有第二个参数,则使用没有意义,页面渲染,该值还是会重新生成,。
- 若第二个参数为,则代表没有依赖,页面首次渲染时将该值缓存,之后不再变化。
- 若第二个参数,,则当改变时,React会第一个参数并将返回的值进行缓存。
- 传入的函数会在执行。
使用场景:
一组账号密码对应着一个人的个人信息,默认将登录成功后的账号密码缓存,并将账号密码作为依赖项,当任一依赖项改变,切换个人信息。
简介:
useRef 是用来保存一个在组件的生命周期中持续存在的值,对这个值的修改不会引发组件的重新渲染。这个值可以是DOM引用,也可以是任何可变的数据。
用法:
- useRef返回一个可变的ref对象,该对象只有一个current属性,current属性的初始值为传入的参数initValue。
如:
打印结果:
- 更新ref对象上current属性的值不会触发重渲染(re-render)
- 返回的ref对象在组件的整个生命周期中保持不变
代码:(使用ref.current存值)
效果:
代码:(使用ref.current存DOM节点)
效果:
简介:
- 接收3个参数,ref(该ref用于确认与哪个组件建立起联系,ref由父组件传入),个回调函数,最终返回一个值,这个值是任意的,返回的值给‘提供的这个组件使用’,依赖项。
- 依赖项改变,将会重新第二个参数(回调函数)。:提供给父组件使用的值可能会发生改变。
- 使用需要绑定ref,而ref只能从父级传入,所以该Hook需要与一起使用,当使用useRef创建ref并绑定在函数式组件上时,由于函数组件没有实例,当在父组件获取ref上的current属性时,控制台会报错,而报错信息推荐我们使用函数组件没有实例不可绑定ref的问题。所以说当我们去使用useImperativeHandle Hook时要与useRef、forwordRef配合使用。
- React.forwordRef,也可以理解为子组件向父组件暴露DOM引用。
两个案例:
效果图:
代码实现:
效果图:
代码实现:
简介:
和用法一致,只是不同。且useEffect Hook是异步的,而useLayout Hook是同步执行的。
打印结果:
问题:
- useLayoutEffect Hook不是同步的吗?打印结果不应该是【1、2、useLayoutEffect、3、Effect】?
- 这里说的指的是‘‘React会在所有的 DOM 变更之后 effect’’。。所以说当useLayoutEffect Hook的effect callback执行时DOM是还没渲染到页面上的,执行时机可以类比于。
- componentDidMount也是会在浏览器触发,即使render函数被调用多次(意味着改变了状态),用户也看不到中间状态。
- 什么意思?
- 不管useLayoutEffect还是useEffect,它们的执行时机都是在的。函数的render方法在哪里?
- render函数在React中有两种形式
①在类组件中指的是
②在函数组件中render函数指的是
也就是说:
- 是先执行了render方法才执行的useLayoutEffect/useEffect,这也就解释了为什么先打印出1、2、3了。
- 在过程中,React将新调用的函数返回的树与旧版本的树进行比较,这一步是决定如何更新的必要步骤,然后进行比较,更新树。而的存在是为了操作这些DOM,最终生成DOM,浏览器再绘制渲染到页面的这么一个过程。
执行时机:
- :DOM节点已加载完毕,浏览器后延迟执行effect callback
- :DOM节点已加载完毕,浏览器执行effect callback
假设:
- 通过某个事件更改了某个状态(state)
- React更新这个状态(state)
- React处理组件中return出来的DOM节点(diff算法)
- 浏览器绘制更新之后的DOM
- 渲染完成,将真实DOM展示在页面上
①:useLayoutEffect Hook是在第三点结束,第四点即将要开始时同步执行。。
②:useEffect Hook是在第五点结束后,浏览器什么时候闲了什么时候执行。
用法:(与useEffect用法一致,区别仅在触发时机不同)
效果:
总是在下一次更新前清除上一次的副作用(effect)
总结:
与用法一致,区别在调用时机。
简介:
Hook用于,从而腾出CPU资源来渲染优先级更高的更新,最终目的是提高用户体验。
用法:
- 这个Hook接收一个值并返回一个副本,该副本会被。
- 延迟渲染的意思是:其他的渲染优先级该副本的渲染优先级,该副本将仅剩本身未渲染时开始渲染。
应用场景
- 数据量很大,导致页面卡顿,可以考虑使用这个Hook。
需求:
有10万条数据,根据在输入框中的输入筛选出有关数据
代码演示:
下面会用两种方式进行演示:① ②
第一种:
代码效果:
解释&问题:
- React18提出了一个概念 - “”,翻译成中文是,有点像同步、异步的意思。
- 可以这么理解:React将处理通道由1个变成2个,一个是,而另一个是。
- ,就算A已经准备就绪,但还是要等待B处理完成,然后A、B同时渲染到页面上。这样的后果是:当数据量庞大时,A已经好了,B没好,等一段时间B好了,A、B同时出现在页面上,用户体验感极差。
- 上面的案例就是,键盘输入已经完成,但数据还未筛选出,渲染键盘输入的字符要等到筛选出数据之后才能渲染,导致卡顿,给人的感觉极差。
第二种:
先看效果:
使用了该Hook后,不管是从速度上还是视觉上,都有了极大的提升!
代码:
解释:
- 将一个value值传入useDeferredValue这个Hook,它会返回一个值(),React会将该副本放入,在慢速通道的渲染都会滞后!
- 慢速通道的是在。
- 意思是:当A已处理完成但B因为某种原因处理时间较长时,可将B的值传给该Hook,使用其返回值,这样就不会因为B的处理时间长而影响了A的渲染。有点的意思。
- 上述案例就是利用React18提出的“”来解决数据量庞大,耗时长的问题。
简介:
与作用相同,都是将‘’加入到慢速通道,延迟渲染。但它们用法不同,也有区别,之后会介绍。
参数介绍:
- startTransition: 接收一个回调函数,在回调函数中设置更新,可将更新加入到慢速通道,延迟由该状态导致的UI渲染,换句话说,。
为什么需要这个功能存在?
- 请记住,。React默认是等待所有更新都完成再同时渲染,的出现避免了这一现象,使用它时,轻量级、紧急的渲染将不会被阻塞!
- 允许你将应用程序中的某些更新,因此它们会暂停,同时优先考虑。这使您的应用程序感觉更快,因此,无论你在渲染什么,你的应用程序仍在响应用户的操作。
如果你想在等待昂贵的UI渲染完成时显示一些内容怎么办?你可能显示一个进度条以向用户提供即时反馈,以便用户知道应用程序正在处理他们的请求。
为此,我们可以使用来自 Hook(钩子)的变量。
- isPending: 值为true/false,翻译为中文:。当isPending为真时,说明目前处在,说明startTransition中的回调函数,我们可以利用isPending为True的这一特性,增加一行提示,告知用户,如:
isPending为false时,说明在慢速通道的UI渲染已全部完成。
需求:
跟useDeferredValue这个Hook的需求一样,都是根据输入框键入内容从10万条数据中筛选出相关数据。
如果你没有利用React18新提出的‘’特性,一旦数据量大,处理速度就慢,一些轻量级的渲染将要等待‘这数据量大的处理(根据键盘键入从十万条数据中筛选出相关数据)’完之后,在页面上,页面将会出现卡顿、延迟的现象,用户体验极感极差。
直接来看使用钩子函数后的效果???
效果:
代码:
问题:
- useDeferredValue和useTransition功能都一样,为什么React要创建这两个功能一样的Hook?
- ,而是用来更新函数执行后所更新的的。有些情况下,你并不能直接获得更新函数,比如你用的是第三方的hooks库,在使用的时候更新函数并不能直接对外暴露,这个时候你只能去优化数据,从而你只能使用useDeferredValue这个Hook。
- useTransition的好处是它可以。
注意事项:
- 对于同一个资源的优化,这两个Hook提供的优化效果是一样的,因此不需要同时使用;一旦同时使用,将会带来不必要的性能损耗
- 建议只有数据量大的时候才去考虑这两个Hook。
- 优先使用useTransition Hook,因为isPending变量能给用户带来不一样的视觉效果。
- 不要试图去讨好这个世界,你是这世界唯一的你。 --- 自由极光《这世界唯一的你》
- 感谢我滴导师,wuwuwu~~ 大佬大佬大佬
版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/yd-react-native/22570.html