【知识总结】前端高频React面试题合集

React中keys的作用是什么

keys是react用于追踪哪些元素被修改、 被添加、被移除的辅助标示。

render(){
    
    
	return(
		<ul>
			{
    
    
				this.state.list.map(({
     
     item,key})=>{
    
    
					return <li key={
    
    key}> {
    
    item} </li>
				})
			}
		</ul>
	)
}

在开发过程中,我们需要保证某个元素的key在其同级元素中具有唯一性。

在react diff算法中react会借助元素的key来判断元素是新创建的还是被移动而来的元素,从而减少不必要的元素重新渲染。此外,react还需要借助key值来判断元素与本地状态的关联关系,因此我们绝不可忽视转换函数中key的重要性。

当调用setState的时候,发生了什么

将传递给setState的对象合并到组件的当前状态,这将启动一个和解的过程,构建一个新的react元素树,与上一个元素树进行对比(diff),进而最小化的重渲染。

为什么setState的参数是一个callback

因为this.propsthis.state的更新是异步的,不能依赖它们的值去计算下一个state

状态state和属性props之间有什么区别

  • state是一种数据结构,用于组件挂载时需要数据的默认值。
  • state可能会随着时间的推移而发生突变,但多数时候是作为用户事件行为的结果。
  • props则是组件的配置。props由父组件传递给子组件,并且就子组件而言,props是不可变的。
  • 组件不能改变自身的props,但是可以把子组件的props放在一起,统一管理。props也不仅仅是数据,回调函数也可以通过props传递。

应该在React组件的何处发起Ajax请求

在React组件中,应该在componentDidMount中发起网络请求。这个方法会在组件第一次“挂载”时执行,在组件的生命周期中仅会执行一次。

更重要的是,不能保证在组件挂载之间Ajax请求已经完成,如果是这样,也就以为在将尝试在一个为挂载的组件上调用setState,这不会起任何作用。

所有在componentDidMount中发起网络请求就保证了这一个组件可以更新了。

React中的三种组件构建的方式

React.createClass() 、ES6 Class 、无状态函数

React中的refs的作用是什么

Refs是<span></span> React提供给我们的安全访问DOM元素或者某个组件实例的句柄。
我们可以为元素添加ref属性,然后在回调函数中接受该元素在DOM树中的句柄,该值会作为回调函数的第一个参数返回:

class CustomForm extends Component{
    
    
	handleSubmit = () => {
    
    
		console.log('Input Value: ',this.input.value);
	};
	render(){
    
    
		return(
			<form onSubmit={
    
    this.handleSubmit}>
				<input type='text' ref={
    
    input=> (this.input = input)}/>
				<button type='submit'> Submit </button>
			</form>
		)
	}
}

上面例子中input包含了一个ref属性,该属性声明的回调函数会接收input对应的DOM元素,我们将其绑定到指定this指针以便在其他的类函数中使用。

描述react diff的原理

把树形结构按层级分解,只比较同级元素。

给列表结构的每一个单元添加唯一的key属性,方便比较。

react只会匹配相同的class的component合并操作,调用component的setState的时候,react将其标记为dirty,到每一个事件循环结束,react检查所有标记dirty的component重新绘制,选择性子树渲染。

开发人员可以重写shouldComponentUpdate提高diff的性能。

说说React的优势

  1. react速度很快:它并不直接对DOM进行操作,引入了一个叫做虚拟DOM的概念,安插在JavaScript逻辑和实际DOM直接,性能好。
  2. 跨浏览器兼容:虚拟DOM帮助我们解决了跨浏览器问题,为我们提供了标准化的API,甚至在IE8中都是没问题的。
  3. 一切都是component:代码更加模块化,重用代码更容易,可维护性高。
  4. 单向数据流,Flux树一个用于在JavaScript应用中创建单向数据层的结构,它随着React视图库的开放而被Facebook概念化。
  5. 同构、纯粹的JavaScript:因为搜索引擎的爬虫程序依赖的是服务端相应而不是JavaScript的执行,预渲染你的应用有助于搜索引擎优化。
  6. 兼容性好:比如使用RequireJS来加载和打包,而Broeserify和Webpack适用于构建大型应用。

react生命周期函数有哪些

  • getDefaultProps:获取实例的默认属性
  • getInitialState:获取每个实例的初始化状态
  • componentWillMount:组件即将被装载、渲染在页面上
  • render:组件在这里生成虚拟DOM节点
  • componentDidMount:组件真正的被装载之后运行中状态
  • componentWillReceiveProps:组件将要接收到属性的时候调用
  • shouldComponentUpdate:组件接受到新属性或者新状态的时候
  • componentWillUpdate:组件即将更新不能修改属性和状态
  • render:组件重新描绘
  • componentDidUpdate:组件已更新
  • componetWillUnmount:组件即将销毁

this的各种情况

call、apply、bind指的是this上谁就是谁

  • fun.call (obj, a, b)
  • fun.apply (obj, [ ])
  • fun.bind(obj, a, b)()

this的情况:

  • 以函数形式调用,this永远都是window
  • 以方法的形式调用,this是调用方法的对象
  • 以构造函数的形式调用,this新创建的那个对象
  • 使用call和apply调用,this是指定的那个对象
  • 箭头函数:箭头函数的this看外层是否有函数。如果有,外层函数的this就是内部箭头函数的this;如果没有,就是window
  • 特殊情况:通常意义上this指针指向为最后调用它的对象。这里需要注意的一点是如果返回值是一个对象,那么this指向的就是那个返回的对象。如果返回值不是一个对象,那么this还是指向函数的实例。

介绍promise,异常捕获,如果进行异常处理

promise是解决回调地狱的好工具,比起直接使用回调函数promise的语法更加清晰,代码的可读性大大增加。

老旧浏览器没有promise全局对象怎么办?

可以使用es6-promise-polyfill,可以使用页面标签直接引入,也可以使用es6的import方法引入。引入之后,它就会在window对象中加入promise对象,这样我们就可以全局使用promise了。

如何进行异常处理?

参照promise的文档,我们可以在reject回调和catch中处理异常。但promise规定如果一个错误在reject函数中被处理,那么promise将从异常常态中恢复过来。这意味着接下来的then方法将接收一个resolve回调。

大多数时候我们希望发生错误的时候,promise处理当前的异常并中断后续的then操作。我们先来看一个使用reject处理异常的例子:

var promiseStart = new Promise(function(resolve, reject){
    
    
	reject('promise is rejected');
});
promiseStart.then(function(response){
    
    
	console.log('resolved');
	return new Promise(function(resolve,reject){
    
    
		resolve('promise is resolved');
	});
})
.then(function(response){
    
    
	console.log('resolved:',response);
})
.catch(function(error){
    
    
	console.log('catched:',error);
})

输出:
catched: promise is resolved

React怎么做数据的检查和变化

  • props:组件属性, 专门用来连接父子组件间通信,父组件传输父类成员,子组件可以利用但不能编辑父类成员。
  • state:专门负责保存和改变组件内部的状态。

数据传递

在react中,父组件给子组件传递数据时,通过给子组件设置props的方式,子组件取得props中的值,即可完成数据传递。被传递数据的格式是可以是任何js可识别的数据结构。

数据改变

props不能被自身修改,如果组件内部的属性发生变化使用state。

react会实时监听每个组件的props和state的值,一旦有变化,会立刻更新组件,将结果重新渲染到页面上。

介绍常见的react优化方式

react渲染性能优化的三个方向:

  • 减少计算量:对应到react中就是减少渲染的节点,或者降低组件渲染的复杂度。
  • 利用缓存:对应到react中就是如何避免重新渲染,利用函数式编程的memo方式来避免组件重新渲染。
  • 精确重新计算的范围:对应到react中就是绑定组件和状态的关系,精确判断更新的时机和范围,降低渲染范围。

文件上传如何做断点续传

核心是利用Blob.prototype.slice方法,它和数组的slice方法相似,调用的slice方法可以返回原文件的某个切片。

这样我们就可以根据预先设置好的切片最大数量将文件切分为一个个切片,然后借助http的可并发性,同时上传多个切片,这样从原文传一个大文件,变成了同时传多个小的文件切片,可以大大减少上传时间。

另外由于是并发,传输到服务器的顺序可能会发现变化,所有我们还需要给每个切片记录顺序。

通过什么方式做到并发请求

使用异步promise ALL 或者web wroker

redux的主要作用和使用方式

主要作用:把所有的state集中到组件顶部,能够灵活的将所有的state各取所需的分发给所有的组件。

  • store:保存数据的地方
  • state:包含所有的数据,一个state对应一个view。只要state相同,view就相同。
  • action:view发出的通知action,改变state,从而改变view。修改state的唯一办法就是action。

React组件通信方式如何?

父传子

父组件向子组件通过props的方式,向子组件进行通信。

子传父

props + 回调的方式,父组件向子组件传递props进行通讯,此props的作用与为父组件自身的函数,子组件调用该函数,将子组件要传递的信息作为参数传递到父组件的作用域中。

兄弟间

找到这两个兄弟节点共同的父节点,结合上面两种方式,由父组件转发信息进行通信。

跨层级通信

context设计目的是为了共享哪些对于一个组件树而言是“全局”的数据,例如当前认证的用户、主题、首选语言,对于跨越多层的全局数据通过context通信再合适不过。

const StateContext = React.createContext()
class Parent extends React.Component{
    
    
	render(
		return(
			<StateContext.Provider value='hello'> //value就是传入Context的值
				<Child/>
			</StateContext.Provider>
		)
	)
}
class Child extends React.Component{
    
    
	render(){
    
    
		return(
			<ThemeContext.Consumer>
			{
    
    
				context=>(
					name is {
    
    context} //取出值
				)
			}
			</ThemeContext.Consumer>
		)}
}

发布订阅模式

发布者发布事件,订阅者监听事件并做出反应,我们可以通过引入event模块进行通信。

全局状态管理工具

借助redux 或者 Mobx等全局状态管理工具进行通信,这种工具会维护一个全局状态中心Store,并根据不同的事件产生新的状态。

redux 中如何进行异步操作

当然,我们可以在componentDidmount中直接进行请求无需借助redux。

但在一定规模的项目中,上述方法很难进行异步流的管理,通常情况下我们会借助redux的异步中间件进行异步处理。

redux的异步流中间件其实又很多,当下主流的异步中间件只有两种:redux-thunk、redux-saga,当然redux-observable可能也有资格占据一席之地。

React如何进行组件/逻辑复用

抛开已被官方弃用的Mixin,组件抽象的技术目前有三种比较主流:

1)高阶组件

高阶组件是react中服用逻辑的一种高级技巧。简而言之,高阶组件就是一个函数,它接受一个组件为参数,返回一个新的组件。

高阶组件定义:

function HocComponent(WrappedComponent){
    
    
	return class ProxyComponent extends React.Component{
    
    
		render(){
    
    
			return <WrappedComponent {
    
    ...this.props}>
		}
	}
}

高阶组件约定:

  • 将不相关的props传递给被包裹的组件
  • 最大化可组合性
  • 包装显示名称以便轻松调试

高阶组件注意事项:

  • 不要在函数内修改原组件
  • 使用反向继承方式时,会丢失原本的显示名
  • 不要在render函数中使用HOC

高阶组件的缺点:

  • 难以溯源。如果原始组件A通过好几个HOC的构造,最终生成了组件B,不知道哪个属性来自于哪个HOC,需要翻看每个HOC才知道各自做了什么事情。
  • props属性名的冲突。某个属性可能被多个HOC重复使用。
  • 静态构建。新的组件是在页面构建之前完成,先有组件,后生成页面。

2)渲染属性(render props)

render props 是一个用于告知组件渲染什么内容的函数属性。该函数返回一个组件,是渲染出来的内容。

作用是为了功能的复用,与HOC类似;其次是组件间的数据单项传递。

相对于高阶组件的优点:

  • 不用担心props的命名冲突问题。
  • 可以溯源,子组件的props一定来自父组件。
  • 是动态构建的,页面在渲染后,可以动态地决定渲染哪个组件。
  • 所有能用HOC完成的事情,render props都可以做,且更加灵活。
  • 除了功能复用,还可以用作两个组件的单向数据传递。

3)Hooks(推荐使用)

在一个函数中定义的state,可以直接拿到另一个函数中使用,有了hooks,这种看似不可能的语法确实行得通。hook的优势不仅体现在代码量上,从风格上来说,也显得语义更清晰、结构更优雅。

更重要的是,上述两种模式的种种缺点,它一个都没有

类组件和函数组件之间的区别是啥

  • 类组件可以使用其他特性,如状态state和生命周期钩子。
  • 当组件只接受props渲染到页面,就是无状态组件,就属于函数组件,也被称为哑组件或者展示组件。
  • 函数组件和类组件当然是有区别的,而且函数组件的性能比类组件的性能要高,因为类组件使用的时候要实例化,而函数组件直接执行函数取返回结构即可。为了提高性能,尽量使用函数组件。
  • 区别函数组件和类组件看是否有this、是否有生命周期、是否有状态state

你了解Virtual DOM吗?解释一下它的工作原理

Virtual DOM是一个轻量级的JavaScript对象,它最初是real DOM的副本。它是一个节点树,将元素、属性、内容作为对象及其属性。

react的渲染函数从react组件中创建一个节点树。然后它响应数据模型的变化来更新树,该变化是由用户或系统完成的各种动作引起的。

Virtual DOM有三个简单的步骤:

  1. 每当底层数据发生改变时,整个UI都将在Virtual DOM描述中重新渲染。
  2. 然后计算之前的DOM表示与新表述的之间的差异。
  3. 完成计算后,将只用实际更改的内容更新real DOM。

MVC框架的主要问题是什么

  • 对DOM操作的代价非常高
  • 程序运行缓慢且效率低下
  • 内容浪费严重
  • 由于循环依赖性,组件模型需要围绕models和views进行创建

解释Reducer的作用

reducers是纯函数,它规定应用程序的状态怎样因响应Action而变化。reducer通过接受先前的状态和action来工作,然后它返回一个新的状态。它根据操作的类型确定需要执行哪种更新,然后返回新的值。如果不需要完成任务,它会返回原来的状态。

Redux有哪些优点

  • 结果可预测性:由于总是存在一个真实来源,即store,因此不存在如何将当前状态与动作和应用的其他部分同步的问题。
  • 可维护性:代码变得更容易维护,具有可预测的结果和严格的结构。
  • 服务器端渲染:你只需要将服务器上创建的store传到客户端即可。这对初始渲染非常有用,并且可以优化应用性能,从而提供更好的用户体验。
  • 开发人员工具:从操作到状态更改,开发人员都可以实时跟踪应用中发生的所有事情。
  • 易于测试:redux的代码主要是小巧、纯碎和独立的功能。这使代码可测试且独立。

为什么React Router中使用switch关键字

当你想要仅显示要在多个定义的路由中呈现单个路由时,可以使用switch关键字。它会按顺序将已定义的URL与已定义的路由进行匹配,找到第一个匹配项后,它将渲染指定的路径,从而绕过其他路线。

说说React Router的优点

  • 无需手动设置历史值:在react router v4中,我们要做的就是将路由包装在<BrowserRouter>组件中。
  • 包是分开的:共有三个包,分别用于Web、Native、Core,这使我们应用更加紧凑。

列出Redux的组件

  • Action:用来描述发生了什么事情的对象
  • Reducer:确定状态将来如何变化的地方
  • Store:整个程序的状态/对象树保存在Store
  • View:只显示Store提供的数据

在构造函数中调用super(props)的目的是什么

  • 在super()被调用之前,子类是不能使用this的,在ES2015中,子类必须在constructor中调用super()
  • 传递props给super()的原因是便于在子类中能在constructor访问this.props

除了在构造函数中绑定this,还有其他方式吗

可以使用属性初始值设定项property initializers来正确绑定回调,create-react-app也是默认支持的。

如果告诉react它应该是编译生产环境版本

通常情况下,我们会使用Webpack和DefinePlugin方法来将NODE_ENV变量值设置为production。

编译版本中react忽略了propType验证以及其他的告警信息,同时还会降低代码库的大小,react是用来Uglify插件来移除生产环境下不必要的注释等信息。

shouldComponentUpdate的作用

shouldComponentUpdate允许我们手动的判断是否要进行组件更新根据组件的应用设置函数的合理返回值能够帮我们避免不必要的更新。

createElement和cloneElement的区别是什么

createElement函数是JSX编译之后使用的创建的函数。

cloneElement是用于复制某个元素并传入新的props。

你用过哪些redux中间件

中间件提供第三方插件的模式自定义拦截:

action -> reducer的过程变为action -> middlewares -> reducer

这种机制可以让我们改变数据流实现异步action

  • redux-logger:提供日志输出
  • redux-thunk:处理异步操作
  • redux-promies:处理异步操作,actionCreator的返回值是promis

redux有什么缺点

一个组件所需要的数据必须由父组件传递过来。

当一个组件相关数据更新时即使父组件不需要用到这个组件,父组件还是会从重新render可能有效率影响或者要写更复杂的shouldComponentUpdate进行判断。

React Portal有哪些使用场景

在以前react中所有的组件都会位于#app 下而使用Portals提供了一种脱离#app的组件,因此Portals适合脱离文档流的组件特别是:position:absoluteposition:fixed的组件。

React Hooks当中的useEffect是如何区分生命周期钩子的

useEffect可以看成是componentDidMound、componentDidupdate、componentWillUnmount三者的结合。

useEffect(callback, [source])接受两个参数的调用方式如下:

useEffect(()=>{
    
    
	console.log('mounted');
	return ()=>{
    
    
		console.log('willUnmount');
	}
},[source]);

生命周期函数的调用主要是通过第二个参数[source]来进行控制有如下几个情况:

  • [source]参数不传时:每次都会优先调用上次保存的函数中返回的那个函数,再调用外部那个函数。
  • [source]参数传[ ]时:外部的函数只会在初始化时调用一次返回的那个函数,也只会最终在组件卸载时调用一次。
  • [source]参数有值时:只会监听到数组中的值发生变化后,优先调用返回的那个函数,再调用外部的函数。

React实现的移动应用中如果出现卡顿有哪些可以考虑的优化方案

  • 增加shouldComponentUpdate钩子对新旧props进行比较,如果值相同则阻止更新,避免不必要的渲染,或者使用PureReactComponent替代Component其内部已经封装来shouldComponentUpdate的浅比较逻辑。
  • 对于列表或其他结构相同的节点,为其中每一项增加唯一key属性方便react的diff算法中对该节点的复用,减少节点的创建和删除操作。
  • 组件的props如果需要经过一系列运算后才能拿到最终结果可以考虑使用reselect库对结果进行缓存。
  • webpack-bundle-analyzer分析当前页面的依赖包是否存在不合理性,如果存在着到并进行优化。

关于生命周期钩子useEffect

在React Hooks中useEffect可以看作是componentDidMountcomponentDidUpdatecomponentWillUnmount的结合。

  • useEffect(callback,[source])接收两个参数
  • callback:钩子回调函数
  • source:设置触发条件,仅当source发生改变时才会触发
  • useEffect钩子在没穿入[source]参数时默认在每次render时都会优先调用上次保存的回调返回的函数后在重新调用回调

通过第二个参数我们便可以模拟出几个常用的生命周期:

  • componentDidMount:传入[ ]时就只会在初始化时调用一次
  • const useMount = (fn)=> useEffect(fn, [ ] )
  • componentWillUnmount:传入[ ]回调中的返回函数也只会被最终执行一次
  • const useUnmount = (fn)=> useEffect(()=>fn, [ ])
  • mounted:可以使用useState封装才一个高度可服用的mounted状态
const useMounted = () => {
    
    
	const [mounted,setMounted] = useState(false);
	useEffect(()=>{
    
    
		!mounted && setMounted(true);
		return ()=> setMounted(false);
	},[]);
	return mounted;
}
componentDidUpdate: useEffect每次均会执行其实就是排除了DidMount后即可
const mounted = useMounted()
useEffect (()=>{
    
    
	mounted && fn()
})

其他内置钩子:

  • useContext:获取context对象
  • useReducer:类似于redux思想的实现但其并不足以替代redux可以理解成一个组件内部的redux。
  • useCallback:缓存回调函数避免传入的回调每次都是新的函数实例而导致依赖组件重新渲染具有性能优化的效果。
  • useMemo:用于缓存传入的props避免依赖的组件每次都重新渲染
  • useRef:获取组件的真实节点
  • useEffect属于异步执行并不会等待DOM真正渲染后执行,而useLayoutEffect则会真正渲染后才触发。

pureComponent和FunctionComponent区别

pureComponent和component完全相同。

但是在shouldComponentUpdate实现中pureComponent使用了props和state浅比较。

主要作用是用来提高某些特定场景的性能。

redux实现原理

为什么用redux

在react中数据在组件中是单向流动的,数据从一个方向父组件流向子组件通过props,所有两个非父组件间通信相对麻烦,redux的出现就是为了解决state里面的数据问题

redux设计理念

redux是将整个应用状态存储到一个地方称为store,里面保存着一个状态树store tree,
组件可以派发dispatch行为给store,而不是直接通知其他组件,组件内部通过订阅store中的状态state来刷新自己的视图。

redux的三大原则

  1. 唯一数据源:整个应用的state都被存储到一个状态树里面,并且这个状态树只存在于唯一的store中
  2. 保持只读状态:state是只读的,唯一改变state的方法就是触发action,action是一个用于描述以发生时间的普通对象。
  3. 数据改变只能通过纯函数来执行:使用纯函数来执行修改为了描述action如何改变state的你需要编写一个reducers

connect原理

首先connect之所以会成功是因为Provider组件,在原应用组件上包裹一层使原来整个应用成为Provider的子组件。接收redux的store作为props通过context对象传递给子孙组件上的connect。

connect上一个高阶函数,首先传入mapStateToProps、mapDispatchToProps,然后返回一个生产component的函数,再将真正的component作为参数传入wrapWithConnect,这样就生产出一个经过包裹的connect组件,该组件具有如下特点:

  • 通过props.store获取祖先的component的store
  • props暴多state props、dispatchprops、parentprops,合并一起得到nextState作为props传给真正的component componentDidMount时添加事件this.store.subscribe实现页面交互
  • shouldComponentUpdate时判断是否有避免进行渲染提升页面性能并得到nextState

React的渲染过程中兄弟节点之间是怎么处理key值不一样的时候

通常我们输出节点的时候都是map一个数组,然后返回一个ReactNode,为了方便内部进行优化,我们必须给每一个ReactNode添加key,这个key prop再设计值处不是给开发者用的,而是给react用的,大概的作用就是给每一个ReactNode添加一个身份标识,以方便react进行识别在重渲染过程中如果key一样,若有组件属性变化,则react只更新组件对于的属性;反之若无属性变化,则不更新;如果key不一样则react先销毁组件然后重新创建该组件。

react-router里面的<Link>标签和<a>标签有什么区别

react-router是伴随着react框架出现的路有系统,它也是公认的一种优秀的路有解决方案。

在使用react-router时候,我们常常会使用其自带的路径跳转组件Link实现,对比a标签,Link组件避免了不必要的重渲染。

setState到底是异步还是同步

有时候表现出异步,有时候表现出同步

  • setState只在合成事件和钩子函数中是异步的,在原生事件和setTimeout中都是同步的
  • setState的异步并不是说内部由异步代码实现,其本身执行的过程和代码都是同步的,只是合成事件和钩子函数的调用顺序在更新之前,导致它们没法立刻拿到更新后的值。
  • 形成了所谓的异步可以通过第二个参数setState(partialState,callback)中的callback拿到更新后的结果。
  • setState的批量更新优化也是建立在异步合成事件、钩子函数之上的,在原生事件和setTimeout中不会批量更新。在异步中,如果对同一个值多次进行setState的批量更新,会对其覆盖取最后一次的执行结果。

说说你用react有什么坑点?

  • JSX做表达式判断时候需要强转为boolean类型。
  • 尽量不要在componentWillReviceProps里使用setState,如果一定要使用需要判断结束条件,不然会出现无限重渲染导致页面崩溃。
  • 给组件添加ref的时候尽量不要使用匿名函数,因为当组件更新的时候匿名函数会被当作新的prop处理让ref属性接收到金函数的时候,react内部会先清空ref,也就是会以bull为回调参数先执行一次ref。
  • 遍历子节点的时候不要用index作为组件的key进行传入

react性能优化方案

  • 重写shouldComponentUpdate来避免不必要的dom操作
  • 使用<span></span> production版的react.js
  • 使用key来帮助react识别列表中所有子组件的最小变化

传入setState函数的第二个参数的作用是什么

该函数会在setState函数调用完成并且组件开始重渲染的时候调用,我们可以用该函数来监听渲染是否完成:

this.setState(
	{
    
    username:'heiheihe'},
	()=> console.log('setState has finished and the component has re-rendered')
)
this.setState((prevState,props)=>{
    
    
	return{
    
    
		streak:prevState.streak + props.count
	}
})

react性能优化是哪个周期函数

shouldComponentUpdate这个方法来判断是否需要调用render方法来重新描绘dom。因为dom的描绘非常消耗性能。

猜你喜欢

转载自blog.csdn.net/weixin_42224055/article/details/120375059