知识点总结 REACT
1、react中如何创建一个组件
ES6:class 组件名 extends Component{}
ES5:var App=React.createClass({})
2、render函数什么时候会执行
当this.state或者this.props发生改变的时候render函数执行
3、react中如何对state中的数据进行修改?setState为什么是异步的
修改数据通过this.setState(参数一,参数二)
this.setState是一个异步函数
参数一:需要修改的数据,对象的形式
参数二:修改成功的回调函数,这里相当于componentDidMount,可以获取到数据更新后的DOM结构
this.setState中的第一个参数除了可以写成一个对象以外,还可以写成一个函数,函数中第一个值为prevState,第二个值为prePprops this.setState((prevState,prop)=>{})
为什么setState是异步的:
当批量执行state的时候可以让DOM渲染的更快,也就是说多个setState在执行的过程中还需要被合并。
4、react中如何定义自定义属性,以及限制外部数据的类型
自定义属性:
组件名.defaultProps={
key:val
}
限制外部数据的类型:
①引入propTypes第三方模块
②类型限制
组件名.propTypes={
key:propTypes.类型
}
5、react路由常用的组件配置项
BrowserRouter 路由的根组件,根组件下面只能有一个子元素
HashRouter 路由的根组件,根组件下面只能有一个子元素
withRouter
Route 路由路径对应的文件
Link 进行路由的跳转
NavLink 进行路由的跳转,选中标签的时候NavLink会加上一个class
Switch 被Switch包裹的Route渲染的时候只会渲染一个路径,建议:子页面不要放在Switch中,主页面放在Switch中
Redirect 路由重定向
6、react路由中Route渲染组件的方法有哪几种?区别是什么
①<Route path="/home" component={组件名}></Route>
通过component进行组件的渲染,这种方式的优点在于可以直接在组件的内部接收到history、location、match,缺点在于如果需要传参的组件,或者渲染jsx语法的时候无法使用。
②<Route path="/home" render={()=>{
return <Home/>
}}></Route>
通过render进行渲染组件,优点在于可以进行组件传参,还可以渲染非组件的标签,缺点在于如果需要使用history、location、match的话需要在函数中传递过去。
7、如何控制路由路径的完全匹配
给NavLink或Route设置exact属性
8、react中路由传参的方法有哪些
//方案一:通过params进行传值
<Router path="/one/:id" render={(history)=>{
return <One history={history} />
}}>
</Router>
//html跳转
<NavLink to={"/one/"+1}>one</NavLink>
//js跳转
this.props.history.push("/one/"+"1")
//接收值:在组件内部通过constructor接收
constructor({history,location,match}){
super();
console.log(match.params)
} //方案二:通过query进行传值
<Router path="/one" render={(history)=>{
return <One history={history} />
}}></Router>
//html跳转
<NavLink to={
pathname:"/one"
query:{data:1}
}>one</NavLink>
//js跳转
this.props.history.push({pathname:"/one",query:{data:1}})
//获取值
this.props.location.query.data
注意:如果通过render进行渲染的时候需要在回调中将history的值传递过去,
如果是component进行渲染的话,只需要通过this.props进行接收
9、react中的编程式导航有哪些
this.props.history.push("路径") 跳转路径
this.props.history.back() 返回
this.props.history.forward() 前进
this.props.history.replace() 替换
10、react的生命周期
组件创建的过程:
constructor
componentWillMount
render
componentDidMount
当props中的数据发生改变后会执行哪些生命周期函数:
componentWillReceiveProps
shouldComponentUpdate
componentWillUpdate
render
componentDidUpdate
组件销毁的时候:
componentWillUnmount
11、react中如何强制更新DOM
this.foreUpdate()
12、谈谈对react中生命周期shouldComponentUpdate的理解
shouldComponentUpdate是react性能优化非常重要的一环。组件接收新的state或者props时调用,我们设置在此对比前后两个props和state是否相同,如果相同则返回false阻止更新,因为相同的属性状态一定会产生相同的DOM树,这样就不需要创造新的DOM树和旧的DOM树进行diff算法对比,节省大量性能,尤其是在DOM结构复杂的时候。
13、谈谈你对虚拟DOM的理解,以及好处
虚拟DOM:真实的js对象
好处:虚拟DOM提高了react性能,每次更新数据后都会重新计算上虚拟DOM,并和上一次的虚拟DOM进行对比,对发生变化的部分进行批量更新。react中也提供了shouldComponentUpdate声明周期的回调,来减少数据变化后不必要的虚拟DOM对比过程,保证性能。
14、谈谈对flux的理解
利用单项数据流的方式来组合react的视图组件,它是一种模式,而不是一种框架。
flux可以帮我们解决非父子组件之间的传值
flux数据传递流程
https://www.cnblogs.com/nanianqiming/p/9870194.html
15、react17版本废除的生命周期,与新增的生命周期函数
由于未来采用异步渲染机制,所以即将在17版本中去掉的生命周期钩子函数:
componentWillMount
componentWillReceiveProps
componentWillUpdate
新增的生命周期:
static getDeriveStateFromProps(nextProps,prevState){}
用于替换componentWillReceiveProps,可以用来控制props更新state的过程,它返回一个对象表示新的state,如果不需要更新,返回null即可。在每次渲染之前都会调用,不管初始挂载还是后面的更新都会调用,这一点和componentWillReceiveProps(只有当父组件造成重新渲染时才调用)不同,每次都应该返回新对象。
getSnapshotBeforeUpdate(){}
用于替换componentWillUpdate,该函数会在update后DOM更新前被调用,用于读取最新的DOM数据,返回值将作为componentDidUpdate的第三个参数,在最新的渲染数据提交给DOM前会立即调用,它让你在组件的数据可能要改变之前调用他们。
componentDidCatch(error,info){}
如果一个组件定义了componentDidCatch生命周期,则它将成为一个错误边界。错误边界会捕捉渲染期间,在生命周期中和在它们之下整棵树的构造函数中的错误,就像使用了try catch,不会将错误直接抛出了,保证应用的可能性。
16、this.setState之后做了哪些操作
shouldComponentUpdate
componentWillUpdate
render
componentDidUpdate
17、当组件的key值发生改变后会执行哪些生命周期函数
componentWillUnmount
constructor
componentWillMount
render
componentDidMount
18、在react中是否封装过组件?封装组件要注意的地方
常用封装组件用到的东西
propTypes 限制外部数据的类型
defaultProps 设置默认的外部数据
父传子 子传父 context等传值方式
高阶组件
封装组价要注意组件的复用性、灵活性
19、如何接收组件内部的标签/内容
this.props.children
20、说一下对redux的理解,以及使用的方式
其实redux就是Flux的一种进阶实现,它是一个应用数据流框架,主要作用是应用状态的管理。
redux的三大原则:
①单一的数据源
②state是只读的
③使用纯函数来进行修改
redux中常用的三个方法:
①createStore() 创建store
②combineReducers() 合并多个reducer
③applyMiddleware() 使用中间件,处理异步的action
redux数据传递的流程:
当组件需要改变store的时候,需要创建一个action,然后通过dispatch(action)传递给store,然后store把action转发给reducers。reducers会拿到previousState(以前的state数据)和action。然后将previousState和action进行结合做新的数据(store)修改。然后生成一个新的数据传递给store。store通过触发subscribe方法来调用函数执行setState使得view的视图发生改变。
21、请说下在react中如何处理异步的action
通过applyMiddleware来使用中间件来处理action
常用的中间件:
redux-promise-middleware
redux-thunk
redux-saga
22、请说下对redux中间件的理解
中间件:请求和回复之间的一个应用
在redux中,中间件是dispatch和reducer之间的一个应用
23、请说下redux中你对reducers的理解,以及如何合并多个reducers
在redux中reducer是一个纯函数,其中这个纯函数会接收2个参数,一个是state,一个是action。state用来保存公共的状态,state的特点是只能读不能修改。
在实际开发中因为会涉及到多人协作开发,所以每个模块都有一个reducer,我们可以通过combineReducers来合并多个reducers。
24、请说下对高阶组件的理解,以及作用
高阶组件:它是一个函数,接收一个组件作为参数,返回一个相对增强性的组件。
高阶组件是一个函数,并不是组件。
作用:
①属性代理----主要进行组件的复用(最常见的高阶组件的使用方式,通过做一些操作,将被包裹组件的props和新生成的props一起传递给此组件)
②反向继承----主要进行渲染的劫持(返回的react组件继承了被传入的组件,所以它能访问到的区域、权限更多,想比属性代理的方式,它更像是打入组件内部,对其进行修改)
25、在react中如何解决单页面开发首次加载白屏现象
①通过路由懒加载的方式 react-loadable
②首屏服务端渲染
26、请说下react中key值的理解
react利用key来识别组件,它是一种身份标识,相同的key值react认为是同一个组件,这样后续相同的key对应的组件都不会被创建。
有了key属性后,就可以与组件建立一种对应关系,react根据key来决定是销毁重新创建组件还是更新组件。
key相同,若组件属性有所变化,则react只更新组件对应的属性,没有变化则不更新。
key值不同,则react先销毁该组件(有状态组件的componentWillUnmount会执行),然后重新创建该组件(有状态组件的constructor和componentWIllUnmount都会执行)。
27、组件第一次执行的时候会执行哪些生命周期函数
constructor
componentWillMount
render
componentDidMount
28、哪些声明周期会执行多次
render
componentWillReceiveProps
shouldComponentUpdate
componentWillUpdate
componentDidUpdate
29、当this.state和this.props执行的时候会执行哪些生命周期函数
this.state
shouldComponentUpdate
componentWillUpdate
render
componentDidUpdate
this.props
componentWillReceiveProps
shouldComponentUpdate
render
componentDidUpdate
30、谈谈对context的理解
当不想在组件树中通过逐层传递props或state的方式来传递数据时,可以使用context来实现跨层级的组件数据传递,使用context可以实现跨组件传递。
旧版context的基本使用:
①getChildContext根组件中声明,一个函数,返回一个对象,就是context
②childContextTypes根组件中声明,指定context的结构类型,如不指定会产生错误
③contextTypes子孙组件中声明,指定要接收的context的结构类型,可以只是context的一部分结构。contextTypes没有定义,context将是一个空对象。
④this.context在子孙组件中通过此来获取上下文
新版context的使用:
①根组件中引入GlobalContext,并使用GlobalContext.Provider(生产者)
②组件引入GlobalContext并调用context,使用GlobalContext.Consumer
31、谈谈对react中withRouter的理解
默认情况下必须是经过路由匹配渲染的组件在this.props上拥有路由参数,才能使用编程式导航的写法,withRouter是把不通过路由切换过来的组件,将react-router的history、location、match三个对象传入props对象上。
简单来说就是:不是路由包裹的组件也可以使用路由的一些方法
32、说说对puerComponent的理解
puerComponent表示一个纯组件,可以用来优化react程序,减少render函数渲染的次数,提高性能。
puerComponent进行的是浅比较,也就是说如果是引用数据类型的数据,只会比较不是同一个地址,而不会比较这个地址里的数据是否一致。
好处:当组件更新时,如果组件的props或state都没有改变,render函数就不会触发,省去虚拟DOM的生成和对比过程,达到提升性能的目的。具体原因是react自动帮我们做了一层浅比较。
33、react请求接口数据是在componentDidMount还是componentWillMount周期好
如果你要获取外部数据并加载到组件上,只能在组件“已经”挂载到真是的网页上才能做这件事,其他情况你是加载不到组件的。componentDidMount方法中的代码,是在组件已经完全挂载到网页上才会调用被执行,所以保证数据的加载。
react异步渲染开启的时候,componentWillMount就可能中途被打断,中断之后渲染又要重新做一遍,如果在componentWillMount中做ajax调用,代码里看到只有调用一次,但是实际上可能调用n多次,这个浪费了性能。如果把ajax放在componentDidMount中,因为componentDidMount在第二阶段,所以绝对不会多次重复调用,这里是ajax合适的位置。
34、react性能优化
一、immutable简介
Immutable Data是一旦创建,就不能修改的数据。对Immutable对象的任何修改或添加删除操作都会返回一个新的Immutable对象。Immutable实现的原理是Persistent Data Structure(持久化数据结构),也就是使用旧数据创建新数据时,要保证旧数据同时可用且不变,同时为了避免deepCopy把所有的节点都复制一遍带来的性能损耗。
在js中,引用类型的数据,优点在于频繁的操作数据都是在原对象的基础上修改,不会创建新对象,从而可以有效的利用内存,不会浪费内存,这种特性称为mutable(可变),但恰恰它的优点也是它的缺点,太过于灵活多变在复杂数据的场景下也造成了它的不可控性,假设一个对象在多处用到,在某一处不小心修改了数据,其他地方很难预见到数据是如何改变的,针对这种问题的解决方法,一般就像刚才的例子,会想复制一个新对象,再在新对象上做修改,这无疑会造成更多的性能问题以及内存浪费。
为了解决这种问题,出现了immutable对象,每次修改immutable对象都会创建一个新的不可变对象,而老的对象不会改变。
二、react中如何减少render函数渲染的次数
在react中当this.state、this.props发生改变的时候render函数就会执行,但有些时候this.state、this.props没有发生改变的时候render函数也会执行。那么如何减少render函数的执行次数,可以封装一个BaseComponent来减少react中render函数的执行次数。
import React,{Component}from 'react';
import {is} from 'immutable'; class BaseComponent extends Component {
shouldComponentUpdate(newProps, newState) {
const thisProps = this.props || {};
const thisState = this.state || {};
newState = newState || {};
newProps = newProps || {}; if (Object.keys(thisProps).length !== Object.keys(newProps).length ||
Object.keys(thisState).length !== Object.keys(newState).length) {
return true;
} for (const key in newProps) {
if (!is(thisProps[key], newProps[key])) {
return true;
}
} for (const key in newState) {
if (!is(thisState[key], newState[key])) {
return true;
}
}
return false;
}
} export default BaseComponent;
继承BaseComponent来创建开发中所需要的组件:
import BaseComponent from "@common/BaseComponent"; export default class Home extends BaseComponent{
constructor(){
super()
}
........
}
35、react中key值的作用
react中的key属性,它是一个特殊的属性,它的出现不是给开发者使用的,而是给react自己使用,有了key属性后,就可以与组件建立一种对应关系。react利用key来识别组件,它是一种身份标识,就像每个人都有身份证一样,每个key对应一个组件,相同的key react认为是同一个组件,这样后续相同的key对应的组件都不会被创建。
key值相同:如果两个元素的key相同,且满足第一点元素类型相同,若元素属性有所变化,则react只更新组件对应的属性,这种情况下性能开销会相对较小。
key值不相同:在render函数执行的时候,新旧两个虚拟DOM会进行对比,如果两个元素有不同的key,那么前后两次渲染中就会被认为是不同的元素,这时候旧的那个元素会被销毁,新的元素会被创建。
//更新前
render(){
return(
<List key="1"/>
)
}
//更新后
render(){
return(
<List key="2"/>
)
}
例子:
//tree1
<ul>
<li key="1">1</li>
<li key="2">2</li>
</ul>
//tree2
<ul>
<li key="1">1</li>
<li key="3">3</li>
<li key="2">2</li>
</ul>
如果没有key值,react并不会执行插入操作,它会直接移除原先的第二个子元素,然后在append进去剩下的子元素,而其实我们这个操作只需要一个insert操作就能完成。为了解决这种问题,react需要我们提供一个key来帮助更新,减少性能开销。
如果有key值,react就会通过key来发现剩下tree2的第二个子元素不是原先tree1的第二个元素,原先的第二个元素被挪到下面去了,因此在操作的时候就会直接指向insert操作,来减少DOM操作的性能开销。
不推荐用属性中的index来做key值
大部分情况下我们要在执行数据遍历的时候会用index来表示元素的key,这样做其实并不是很合理。我们用key的真实目的是为了标识前后两次渲染中元素的对应关系,防止发生不必要的更新操作。那么如果我们用index来标识key,数据在执行插入、排序等操作之后,原先的index并不再对应到原先的值,那么这个key就失去了本身的意义,还会带来其他问题。
注意事项
react中的key值必须保证其唯一和稳定性
下面案例中的key值以Math.random()随机生成而定,这使得数组元素中的每项都重新销毁然后重新创建,有一定的性能开销
{
dataList.map((item,index)=>{
return <div key={Math.random()}>{item.name}</div>
})
}
知识点总结 REACT的更多相关文章
- react生命周期知识点
react生命周期知识点 一个React组件的生命周期分为三个部分:实例化.存在期和销毁时. 实例化 组件在客户端被实例化,第一次被创建时,以下方法依次被调用: 1.getDefaultProps2. ...
- react 属性与状态 学习笔记
知识点:1.react 属性的调用 this.props.被调用的属性名 设置属性的常用方法:var props = { one: '123', two: 321}调用这个属性:<HelloWo ...
- React 与 React Native 底层共识:React 是什么
此系列文章将整合我的 React 视频教程与 React Native 书籍中的精华部分,给大家介绍 React 与 React Native 结合学习的方法,此小节主要介绍 React 的底层原理与 ...
- react复习总结(1)--react组件开发基础
这次是年后第一次发文章,也有很长一段时间没有写文章了.准备继续写.总结是必须的. 最近一直在业余时间学习和复习前端相关知识点,在一个公司呆久了,使用的技术不更新,未来真的没有什么前景,特别是我们这种以 ...
- vue.js 知识点(二)
关于vue看到有很多的知识点和react有很多相近的地方,比如说路由还有一些简单的运用,但是又有一些不同,比如格式.还有写法的一些不同! 所以在这里我总结一下关于vue 关于路由的一些运用: 路由: ...
- react深入 - 手写实现react-redux api
简介:简单实现react-redux基础api react-redux api回顾 <Provider store>把store放在context里,所有子组件可以直接拿到store数据 ...
- 一个基于React整套技术栈+Node.js的前端页面制作工具
pagemaker是一个前端页面制作工具,方便产品,运营和视觉的同学迅速开发简单的前端页面,从而可以解放前端同学的工作量.此项目创意来自网易乐得内部项目nfop中的pagemaker项目.原来项目的前 ...
- React实战教程之从零开始手把手教你使用 React 最新特性Hooks API 打造一款计算机知识测验App
项目演示地址 项目演示地址 项目代码结构 前言 React 框架的优雅不言而喻,组件化的编程思想使得React框架开发的项目代码简洁,易懂,但早期 React 类组件的写法略显繁琐.React Hoo ...
- 从0开始,手把手教你使用React开发答题App
项目演示地址 项目演示地址 项目源码 项目源码 其他版本教程 Vue版本 小程序版本 项目代码结构 前言 React 框架的优雅不言而喻,组件化的编程思想使得React框架开发的项目代码简洁,易懂,但 ...
随机推荐
- 在jenkins中处理外部命令7z的异常
powershell中有自己的异常捕获机制,但是在jenkins中处理第三方工具抛出的异常时,一直抓不到,疑惑了很久,本篇内容主要描述此次过程及解决方案. powershell可以处理外部异常 try ...
- axios 源码解析(下) 拦截器的详解
axios的除了初始化配置外,其它有用的应该就是拦截器了,拦截器分为请求拦截器和响应拦截器两种: 请求拦截器 ;在请求发送前进行一些操作,例如在每个请求体里加上token,统一做了处理如果以后要 ...
- Django学习笔记(17)——BBS+Blog项目开发(1)验证码功能的实现
本文主要学习验证码功能的实现,为了项目BBS+Blog项目打下基础. 为了防止机器人频繁登陆网站或者破坏分子恶意登陆,很多用户登录和注册系统都提供了图形验证码功能. 验证码(CAPTCHA)是“Com ...
- python 统计使用技巧
python 统计使用技巧 # 1.不输入回车获取值 注:需要tty模块配合. fd = sys.stdin.fileno() old_settings = termios.tcgetattr(fd) ...
- 【04】Nginx:rewrite / if / return / set 和变量
写在前面的话 我们前面已经谈了编译安装,基本语法,日志处理,location 匹配,root / alias 的不同效果.这里我们主要谈谈 rewrite(重写)功能,顺便说说 nginx 中自带的变 ...
- mysql 开启慢查询及其用mysqldumpslow做日志分析
mysql慢查询日志是mysql提供的一种日志记录,它是用来记录在mysql中相应时间超过阈值的语句,就是指运行时间超过long_query_time值的sql,会被记录在慢查询日志中.long_qu ...
- VM1059 bootstrap-table.min.js:7 Uncaught TypeError: Cannot read property 'classes' of undefined
参考链接:https://blog.csdn.net/liuqianspq/article/details/81868283 1.阳光明媚的下午,我在写CRUD,让数据传到前端的时候,解析的时候报错了 ...
- C# 关于使用JavaScriptSerializer 序列化与返序列化的操作
//开始解析 //引用 //using System.Web.Script.Serialization; JavaScriptSerializer js = new JavaScriptSerial ...
- 解决 Windows Server 2008 R2 上 Windows Update 无法失败,提示 8024402F
1.同步服务器时间 2.打开 services.msc,停止 Windows Update Service 3.手动下载 KB3138615 补丁:https://support.microsoft. ...
- Python简单的get和post请求
1.json 模块提供了一种很简单的方式来编码和解码JSON数据. 其中两个主要的函数是 json.dumps() 和 json.loads() , 要比其他序列化函数库如pickle的接口少得多. ...