知识点总结 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框架开发的项目代码简洁,易懂,但 ...
随机推荐
- QSS QPushButton:hover :pressed ...为状态下变更字体颜色(color)无效,变成字体粗细(font-weight)有效???
//字体颜色变更无效 QPushButton:hover{ font-weight:bold; color:rgba(, , , ); } //字体颜色变更有效 QPushButton#pushBut ...
- leetcode 410. 分割数组的最大值(二分法)
1. 题目描述 给定一个非负整数数组和一个整数 m,你需要将这个数组分成 m 个非空的连续子数组.设计一个算法使得这 m 个子数组各自和的最大值最小. 注意: 数组长度 n 满足以下条件: 1 ≤ n ...
- Python 将numpy array由浮点型转换为整型
Python 将numpy array由浮点型转换为整型 ——使用numpy中的astype()方法可以实现,如:
- LeetCode 150:逆波兰表达式求值 Evaluate Reverse Polish Notation
题目: 根据逆波兰表示法,求表达式的值. 有效的运算符包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰表达式. Evaluate the value of an arithm ...
- CodeForce 222C Reducing Fractions
To confuse the opponents, the Galactic Empire represents fractions in an unusual format. The fractio ...
- php imagemagick 翻译目录
图像处理(ImageMagick) 介绍 安装/配置 要求 安装 运行时配置 资源类型 预定义常数 例子 基本用法 Imagick - Imagick课 Imagick :: adaptiveBlur ...
- [Delphi]无边框窗口最大化不挡任务栏方法
procedure WMGetMinMaxInfo(var mes: TWMGetMinMaxInfo); message WM_GetMinMaxInfo; procedure TfrmMain.W ...
- matplotlib基础
Matplotlib 基础 注:本文中的程序都默认引入了numpy库和matplotlib库,并且分别简写为np与plt:如果读者不知道怎么使用numpy库,可以移步到这一博客上进行简单的学习 一.简 ...
- 练手WPF(一)——模拟时钟与数字时钟的制作(下)
继续数字时钟.上一篇写好了数字笔划专用的DigitLine类.现在是时候使用它了.下面对一些主要代码进行说明. 打开MainWindow.xaml.cs文件: (1)添加字段变量 // 数字时钟字段定 ...
- 基于SqlClient开发SQLServer工具类 伸手党的福音
注意:代码直接Copy调用即可,SQLServer工具类跟我上一个Oracle工具类有所不同,区别在于调用存储过程中时参数的使用,无需输入对应的存储游标名称 特点:根据用户传入的参数类型来识别存储中对 ...