React常见的面试题以及答案
说说对React的了解?有哪些个性?
辨别Real DOM和Virtual DOM
什么是JSX和它的个性?
类组件和函数组件之间有什么区别?
理解 Virtual DOM 吗?解释一下它的工作原理。
说说对 State 和 Props的了解,有什么区别?
说说对React refs 的了解?利用场景?
setState是同步还是异步
super()和super(props)有什么区别?
说说对React事件机制的了解?
React事件绑定的形式有哪些?区别?
React组件生命周期有几个阶段
具体解释 React 组件的生命周期办法
react在哪个生命周期做优化
受控组件和非受控组件的区别
React组件事件代理的原理
为什么虚构 dom 会进步性能
React中的key有什么作用?
react的diff算法是怎么实现的
react组件之间如何通信
什么是高阶组件?
说说对React Hooks的了解?解决了什么问题?
说说react中引入css的形式有哪几种?区别?
在React中组件间过渡动画如何实现?
React context是什么?
说说你对Redux的了解?其工作原理?
Redux遵循的三个准则是什么?
数据如何通过 Redux 流动?
react-redux的两个最次要性能?
Redux中异步的申请怎么解决
介绍Redux中间件
你在React我的项目中是如何应用Redux的? 我的项目构造是如何划分的?
为什么 React Router 中应用 Switch 关键字 ?

说说对React的了解?有哪些个性?
是什么
React,用于构建用户界面的 JavaScript 库,提供了 UI 层面的解决方案,遵循组件设计模式、申明式编程范式和函数式编程概念,以使前端应用程序更高效,应用虚构DOM来无效地操作DOM,遵循从高阶组件到低阶组件的单向数据流,帮忙咱们将界面成了各个独立的小块,每一个块就是组件,这些组件之间能够组合、嵌套,形成整体页面.

个性

JSX语法
单向数据绑定
虚构DOM
申明式编程
Component(组件化)
劣势

高效灵便
申明式的设计,简略应用
组件式开发,进步代码复用率
单向响应的数据流会比双向绑定的更平安,速度更快
辨别Real DOM和Virtual DOM
Real DOM

Real DOM,实在DOM, 意思为文档对象模型,是一个结构化文本的形象,在页面渲染出的每一个结点都是一个实在DOM构造
更新迟缓
能够间接更新 HTML
如果元素更新,则创立新DOM
DOM操作代价很高
耗费的内存较多
Virtual DOM

Virtual Dom,实质上是以 JavaScript 对象模式存在的对 DOM 的形容。创立虚构DOM目标就是为了更好将虚构的节点渲染到页面视图中,虚构DOM对象的节点与实在DOM的属性一一呼应
更新更快
无奈间接更新 HTML
如果元素更新,则更新 JSX
DOM 操作非常简单
很少的内存耗费
什么是JSX和它的个性?
JSX 是JavaScript XML的缩写,不是html或xml,基于ECMAScript的一种新个性,一种定义带属性树结构的语法;

个性:

自定义组件名首字母大写
嵌套;在render函数中return返回的只能蕴含一个顶层标签,否则也会报错。
求值表达式;JSX根本语法规定,遇到HTML标签(以<结尾),就用HTML规定解析;遇到代码块(以{结尾),就用JS规定解析
驼峰命名
class属性须要写成className
JSX容许间接在模板插入JS变量。如果这个变量是一个数组,则会开展这个数组的所有成员
在JSX中插入用户输出是平安的,默认状况下ReactDOM会在渲染前,本义JSX中的任意值,渲染前,所有的值都被转化为字符串模式,这能预防XSS攻打。
类组件和函数组件之间有什么区别?
类组件:

无论是应用函数或是类来申明一个组件,它决不能批改它本人的 props。
所有 React 组件都必须是纯函数,并禁止批改其本身 props。
React是单项数据流,父组件扭转了属性,那么子组件视图会更新。
属性 props是外界传递过去的,状态 state是组件自身的,状态能够在组件中任意批改
组件的属性和状态扭转都会更新视图。
函数组件:

函数组件接管一个繁多的 props 对象并返回了一个React元素
函数组件的性能比类组件的性能要高,因为类组件应用的时候要实例化,而函数组件间接执行函数取返回后果即可。为了进步性能,尽量应用函数组件。
理解 Virtual DOM 吗?解释一下它的工作原理。
Virtual DOM 是一个轻量级的 JavaScript 对象,它最后只是 real DOM 的正本。它是一个节点树,它将元素、它们的属性和内容作为对象及其属性。 React 的渲染函数从 React 组件中创立一个节点树。而后它响应数据模型中的变动来更新该树,该变动是由用户或零碎实现的各种动作引起的。

Virtual DOM 工作过程有三个简略的步骤:

每当底层数据产生扭转时,整个 UI 都将在 Virtual DOM 形容中从新渲染。
而后计算之前 DOM 示意与新示意的之间的差别。
实现计算后,将只用理论更改的内容更新 real DOM。
说说对 State 和 Props的了解,有什么区别?
State

一个组件的显示状态能够由数据状态和内部参数所决定,而数据状态就是state,个别在 constructor 中初始化
当须要批改外面的值的状态须要通过调用setState来扭转,从而达到更新组件外部数据的作用,并且从新调用组件render办法
setState还能够承受第二个参数,它是一个函数,会在setState调用实现并且组件开始从新渲染时被调用,能够用来监听渲染是否实现
Props

React的核心思想就是组件化思维,页面会被切分成一些独立的、可复用的组件,组件从概念上看就是一个函数,能够承受一个参数作为输出值,这个参数就是props,所以能够把props了解为从内部传入组件外部的数据
react具备单向数据流的个性,所以他的次要作用是从父组件向子组件中传递数据
props除了能够传字符串,数字,还能够传递对象,数组甚至是回调函数
在子组件中,props在外部不可变的,如果想要扭转它看,只能通过内部组件传入新的props来从新渲染子组件,否则子组件的props和展现模式不会扭转
相同点

两者都是 JavaScript 对象
两者都是用于保存信息
props 和 state 都能触发渲染更新
区别

props 是内部传递给组件的,而 state 是在组件内被组件本人治理的,个别在 constructor 中初始化
props 在组件外部是不可批改的,但 state 在组件外部能够进行批改
state 是多变的、能够批改
说说对React refs 的了解?利用场景?
是什么

React 中的 Refs提供了一种形式,容许咱们拜访 DOM节点或在 render办法中创立的 React元素。
实质为ReactDOM.render()返回的组件实例,如果是渲染组件则返回的是组件实例,如果渲染dom则返回的是具体的dom节点。

如何应用

传入字符串,应用时通过 this.refs.传入的字符串的格局获取对应的元素
传入对象,对象是通过 React.createRef() 形式创立进去,应用时获取到创立的对象中存在 current 属性就是对应的元素
传入函数,该函数会在 DOM 被挂载时进行回调,这个函数会传入一个 元素对象,能够本人保留,应用时,间接拿到之前保留的元素对象即可
传入hook,hook是通过 useRef() 形式创立,应用时通过生成hook对象的 current 属性就是对应的元素
利用场景

在某些状况下,咱们会通过应用refs来更新组件,但这种形式并不举荐,过多应用refs,会使组件的实例或者是DOM构造裸露,违反组件封装的准则;

但上面的场景应用refs十分有用:

对Dom元素的焦点管制、内容抉择、管制
对Dom元素的内容设置及媒体播放
对Dom元素的操作和对组件实例的操作
集成第三方 DOM 库
setState是同步还是异步
setState自身并不是异步,之所以会有一种异步办法的表现形式,归根结底还是因为react框架自身的性能机制所导致的。因为每次调用setState都会触发更新,异步操作是为了进步性能,将多个状态合并一起更新,缩小re-render调用。

实现同步:

setState提供了一个回调函数供开发者应用,在回调函数中,咱们能够实时的获取到更新之后的数据。

state = {
number:1
};
componentDidMount(){
this.setState({number:3},()=>{
console.log(this.state.number) // 3
})
}

利用setTimeout

state = {
number:1
};
componentDidMount(){
setTimeout(()=>{
this.setState({number:3})
console.log(this.state.number) //3
},0)
}

还有在原生事件环境下

state = {
number:1
};
componentDidMount() {
document.body.addEventListener(‘click’, this.changeVal, false);
}
changeVal = () => {
this.setState({
number: 3
})
console.log(this.state.number) //3
}

super()和super(props)有什么区别?
在ES6中,通过extends关键字实现类的继承,super关键字实现调用父类,super代替的是父类的构建函数,应用super(xx)相当于调用sup.prototype.constructor.call(this.xx),如果在子类中不应用super关键字,则会引发报错
super()就是将父类中的this对象继承给子类的,没有super()子类就得不到this对象

在React中,类组件是基于es6的标准实现的,继承React.Component,因而如果用到constructor就必须写super()才初始化this,在调用super()的时候,咱们个别都须要传入props作为参数,如果不传进去,React外部也会将其定义在组件实例中,所以无论有没有constructor,在render中this.props都是能够应用的,这是React主动附带的,然而也不倡议应用super()代替super(props),因为在React会在类组件构造函数生成实例后再给this.props赋值,所以在不传递props在super的状况下,调用this.props为undefined,而传入props的则都能失常拜访,确保了 this.props 在构造函数执行结束之前已被赋值,更合乎逻辑

总结

在React中,类组件基于ES6,所以在constructor中必须应用super
在调用super过程,无论是否传入props,React外部都会将porps赋值给组件实例porps属性中
如果只调用了super(),那么this.props在super()和构造函数完结之间仍是undefined
说说对React事件机制的了解?
是什么
React基于浏览器的事件机制本身实现了一套事件机制,包含事件注册、事件的合成、事件冒泡、事件派发等,在React中这套事件机制被称之为合成事件;

合成事件是 React模仿原生 DOM事件所有能力的一个事件对象,即浏览器原生事件的跨浏览器包装器

执行程序

React 所有事件都挂载在 document 对象上
当实在 DOM 元素触发事件,会冒泡到 document 对象后,再解决 React 事件
所以会先执行原生事件,而后解决 React 事件
最初真正执行 document 上挂载的事件
总结

React 上注册的事件最终会绑定在document这个 DOM 上,而不是 React 组件对应的 DOM(缩小内存开销就是因为所有的事件都绑定在 document 上,其余节点没有绑定事件)
React 本身实现了一套事件冒泡机制,所以这也就是为什么咱们 event.stopPropagation()有效的起因。
React 通过队列的模式,从触发的组件向父组件回溯,而后调用他们 JSX 中定义的 callback
React 有一套本人的合成事件 SyntheticEvent
理解更多详情请点击React事件机制的了解

React事件绑定的形式有哪些?区别?
render办法中应用bind

render办法中应用箭头函数

constructor中bind

定义阶段应用箭头函数绑定

class App extends React.Component {
handleClick() {
console.log('this > ', this);
}
render() {
return (

{/ 1.render办法中应用bind/}
test

{/2.render办法中应用箭头函数 /}
<div onClick={e => this.handleClick(e)}>test

)
}
}
class App extends React.Component {
constructor(props) {
super(props);
//3.constructor中bind
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
console.log('this > ', this);
}
render() {
return (
test

)
}
}
class App extends React.Component {
//4.定义阶段应用箭头函数绑定
handleClick = () => {
console.log('this > ', this);
}
render() {
return (
test

)
}
}
区别

编写方面:形式一、形式二写法简略,形式三的编写过于繁杂
性能方面:形式一和形式二在每次组件render的时候都会生成新的办法实例,性能问题欠缺。若该函数作为属性值传给子组件的时候,都会导致额定的渲染。而形式三、形式四只会生成一个办法实例
综合上述,形式四(箭头函数绑定)是最优的事件绑定形式
React组件生命周期有几个阶段
初始渲染阶段:这是组件行将开始其生命之旅并进入 DOM 的阶段。

getDefaultProps:获取实例的默认属性
getInitialState:获取每个实例的初始化状态
componentWillMount:组件行将被装载、渲染到页面上
render:组件在这里生成虚构的 DOM 节点
componentDidMount:组件真正在被装载之后

更新阶段:一旦组件被增加到 DOM,它只有在 prop 或状态发生变化时才可能更新和从新渲染。这些只产生在这个阶段。

componentWillReceiveProps:组件将要接管到属性的时候调用
shouldComponentUpdate:组件承受到新属性或者新状态的时候(能够返回 false,接收数据后不更新,阻止 render 调用,前面的函数不会被继续执行了)
componentWillUpdate:组件行将更新不能批改属性和状态
render:组件从新描述
componentDidUpdate:组件曾经更新

卸载阶段:这是组件生命周期的最初阶段,组件被销毁并从 DOM 中删除。

componentWillUnmount:组件行将销毁

具体解释 React 组件的生命周期办法
componentWillMount() – 在渲染之前执行,在客户端和服务器端都会执行。
componentDidMount() – 仅在第一次渲染后在客户端执行。
componentWillReceiveProps() – 当从父类接管到 props 并且在调用另一个渲染器之前调用。
shouldComponentUpdate() – 依据特定条件返回 true 或 false。如果你心愿更新组件,请返回true ,不想更新组件则返回 false就会阻止render渲染。默认状况下,它返回 true。
componentWillUpdate() – 在 DOM 中进行渲染之前调用。
componentDidUpdate() – 在渲染产生后立刻调用。
componentWillUnmount() – 从 DOM 卸载组件后调用。用于清理内存空间。
react在哪个生命周期做优化
shouldComponentUpdate,这个办法用来判断是否须要调用 render 办法重绘 dom。
因为 dom 的描述十分耗费性能,如果咱们能在这个办法中可能写出更优化的 dom diff 算法,能够极大的进步性能。

点击React学习笔记四——受控组件和非受控组件查看详解

受控组件和非受控组件的区别
受控组件是React管制的组件,input等表单输入框值不存在于 DOM 中,而是以咱们的组件状态存在。每当咱们想要更新值时,咱们就像以前一样调用setState。

不受管制组件是您的表单数据由 DOM 解决,而不是React 组件,Refs 用于获取其以后值;

React组件事件代理的原理
和原生HTML定义事件的惟一区别就是JSX采纳驼峰写法来形容事件名称,大括号中依然是规范的JavaScript表达式,返回一个事件处理函数。在JSX中你不须要关怀什么机会去移除事件绑定,因为React会在对应的实在DOM节点移除时就主动解除了事件绑定。

React并不会真正的绑定事件到每一个具体的元素上,而是采纳事件代理的模式:在根节点document上为每种事件增加惟一的Listener,而后通过事件的target找到实在的触发元素。这样从触发元素到顶层节点之间的所有节点如果有绑定这个事件,React都会触发对应的事件处理函数。这就是所谓的React模仿事件零碎。

为什么虚构 dom 会进步性能
虚构dom(virtual dom) 是 JS对象,是一个实在dom的JS对象;虚构 dom 相当于在 js 和实在 dom 两头加了一个缓存,利用 dom diff 算法防止了没有必要的 dom 操作,从而进步性能。

用 JavaScript 对象构造示意 DOM 树的构造;而后用这个树构建一个真正的 DOM 树,插到文档当中当状态变更的时候,从新结构一棵新的对象树。而后用新的树和旧的树进行比拟,记录两棵树差别把 2 所记录的差别利用到步骤 1 所构建的真正的 DOM 树上,视图就更新了。

React中的key有什么作用?
跟Vue一样,React 也存在diff算法,而元素key属性的作用是用于判断元素是新创建的还是被挪动的元素,从而缩小不必要的Diff,因而key的值须要为每一个元素赋予一个确定的标识。

如果列表数据渲染中,在数据前面插入一条数据,key作用并不大;后面的元素在diff算法中,后面的元素因为是完全相同的,并不会产生删除创立操作,在最初一个比拟的时候,则须要插入到新的DOM树中。因而,在这种状况下,元素有无key属性意义并不大。
如果列表数据渲染中,在后面插入数据时,当领有key的时候,react依据key属性匹配原有树上的子元素以及最新树上的子元素,只须要将元素插入到最后面地位,当没有key的时候,所有的li标签都须要进行批改
并不是领有key值代表性能越高,如果说只是文本内容扭转了,不写key反而性能和效率更高,次要是因为不写key是将所有的文本内容替换一下,节点不会发生变化,而写key则波及到了节点的增和删,发现旧key不存在了,则将其删除,新key在之前没有,则插入,这就减少性能的开销
总结

良好应用key属性是性能优化的十分要害的一步,注意事项为:

key 应该是惟一的
key不要应用随机值(随机数在下一次 render 时,会从新生成一个数字)
防止应用 index 作为 key
react的diff算法是怎么实现的
把树形构造依照层级合成,只比拟同级元素
通过给列表构造的每个单元增加的惟一 key值进行辨别同档次的子节点的比拟。
React 只会匹配雷同 class 的 component(这外面的 class 指的是组件的名字)
合并操作,调用 component 的 setState 办法的时候, React 将其标记为 dirty. 到每一个事件循环完结, React 查看所有标记 dirty 的 component 从新绘制。
选择性渲染。开发人员能够重写 shouldComponentUpdate 进步 diff 的性能。
在这里插入图片形容

react组件之间如何通信
父子:父传子:props; 子传父:子调用父组件中的函数并传参;
兄弟:利用redux实现和利用父组件
所有关系都通用的办法:利用PubSub.js订阅
点击React学习笔记十二——组件之间的通信形式查看具体内容

什么是高阶组件?
高阶组件就是一个函数,且该函数承受一个组件作为参数,并返回一个新的组件。基本上,这是从React的组成性质派生的一种模式,咱们称它们为“纯”组件, 因为它们能够承受任何动静提供的子组件,但它们不会批改或复制其输出组件的任何行为。

高阶组件(HOC)是 React 中用于复用组件逻辑的一种高级技巧
高阶组件的参数为一个组件返回一个新的组件
组件是将 props 转换为 UI,而高阶组件是将组件转换为另一个组件
点击对高阶组件的了解查看详解

说说对React Hooks的了解?解决了什么问题?
Hook 是 React 16.8 的新增个性。它能够让你在不编写 class 的状况下应用 state 以及其余的 React 个性,因而,当初的函数组件也能够是有状态的组件,外部也能够保护本身的状态以及做一些逻辑方面的解决;

最常见的hooks有:useState、useEffect

hooks的呈现,使函数组件的性能失去了裁减,领有了类组件类似的性能;

点击React学习笔记十一——扩大知识点(setState / lazyLoad / Hook / Fragment / Context)查看其中的Hook知识点详解

说说react中引入css的形式有哪几种?区别?
组件式开发抉择适合的css解决方案尤为重要,而在react中,引入CSS就不如Vue不便简洁,其引入css的形式有很多种,各有利弊;

在组件内间接应用
组件中引入 .css 文件
组件中引入 .module.css 文件
CSS in JS
点击 react中引入css的形式查看以上几种引入形式的代码案例

区别

在组件内间接应用css该形式编写不便,容易可能依据状态批改款式属性,然而大量的演示编写容易导致代码凌乱
组件中引入 .css 文件合乎咱们日常的编写习惯,然而作用域是全局的,款式之间会层叠
引入.module.css 文件可能解决部分作用域问题,然而不不便动静批改款式,须要应用内联的形式进行款式的编写
通过css in js 这种办法,能够满足大部分场景的利用,能够相似于预处理器一样款式嵌套、定义、批改状态等
至于应用react用哪种计划引入css,并没有一个相对的答案,能够依据各自状况抉择适合的计划
在React中组件间过渡动画如何实现?
在react中,react-transition-group是一种很好的解决方案,其为元素增加enter,enter-active,exit,exit-active这一系列勾子,能够帮忙咱们不便的实现组件的入场和离场动画

其次要提供了三个次要的组件:

CSSTransition:在前端开发中,联合 CSS 来实现过渡动画成果
SwitchTransition:两个组件显示和暗藏切换时,应用该组件
TransitionGroup:将多个动画组件包裹在其中,个别用于列表中元素的动画
在React中组件间过渡动画查看以上适度组件案例详解

React context是什么?
简略说就是,当你不想在组件树中通过逐层传递props或者state的形式来传递数据时,能够应用Context来实现跨层级的组件数据传递。
在这里插入图片形容
应用props或者state传递数据,数据自顶上流。
在这里插入图片形容
应用Context,能够逾越组件进行数据传递。

说说你对Redux的了解?其工作原理?
redux将所有的状态进行集中管理,当须要更新状态的时候,仅须要对这个治理集中处理,而不必去关怀状态是如何散发到每一个组件外部的,redux是一个实现集中管理的容器,遵循三大根本准则:繁多数据源、state 是只读的、应用纯函数来执行批改;
留神的是,redux并不是只利用在react中,还与其余界面库一起应用,如Vue;

工作原理
redux要求咱们把数据都放在 store公共存储空间,一个组件扭转了 store 里的数据内容,其余组件就能感知到 store的变动,再来取数据,从而间接的实现了这些数据传递的性能

工作流程图如下所示:
在这里插入图片形容
依据流程图,能够设想,React Components 是借书的用户, Action Creactor 是借书时说的话(借什么书), Store 是图书馆管理员,Reducer 是记录本(借什么书,还什么书,在哪儿,须要查一下), state 是书籍信息;

整个流程就是借书的用户须要先存在,而后须要借书,须要一句话来形容借什么书,图书馆管理员听到后须要查一下记录本,理解图书的地位,最初图书馆管理员会把这本书给到这个借书人

转换为代码是,React Components 须要获取一些数据, 而后它就告知 Store 须要获取数据,这就是就是 Action Creactor , Store 接管到之后去 Reducer 查一下, Reducer 会通知 Store 应该给这个组件什么数据

如何应用

点击Redux的了解和应用查看详解和应用案例

Redux遵循的三个准则是什么?
繁多事实起源:整个利用的状态存储在单个 store 中的对象/状态树里。繁多状态树能够更容易地跟踪随工夫的变动,并调试或查看应用程序。
状态是只读的:扭转状态的惟一办法是去触发一个动作。动作是形容变动的一般 JS 对象。就像 state 是数据的最小示意一样,该操作是对数据更改的最小示意。
应用纯函数进行更改:为了指定状态树如何通过操作进行转换,你须要纯函数。纯函数是那些返回值仅取决于其参数值的函数。
数据如何通过 Redux 流动?
在这里插入图片形容

react-redux的两个最次要性能
Provider:提供蕴含store的context
connect:连贯容器组件和傻瓜组件;connect接管两个参数mapStateToProps和mapDispatchToProps。mapStateToProps把Store上的状态转化为内层傻瓜组件的prop,mapDispatchToProps把内层傻瓜组件中的用户动作转化为派送给Store的动作
Redux中异步的申请怎么解决
redux应用redux-thunk中间件解决异步状态治理申请;redux-thunk 容许咱们 dispatch 一个蕴含异步解决逻辑函数(thunk);咱们能够借助这种简略的机制在 redux 中解决异步逻辑;

介绍Redux中间件
什么是中间件:

中间件其实就是一个函数,中间件容许咱们扩大redux应用程序 。具体体现在对action的解决能力上,当组件触发一个action后,这个action会优先被中间件解决,当中间件解决完后,中间件再把action传递给reducer,让reducer持续解决这个action

退出中间件的redux工作流程:
在这里插入图片形容
罕用中间件:

redux-thunk
redux-saga
redux-actions
你在React我的项目中是如何应用Redux的 我的项目构造是如何划分的?
在Redux介绍中,咱们理解到redux是用于数据状态治理,而react是一个视图层面的库。如果将两者连贯在一起,能够应用官网举荐react-redux库,其具备高效且灵便的个性;

react-redux将组件分成:

容器组件:存在逻辑解决
UI 组件:只负责现显示和交互,外部不解决逻辑,状态由内部管制
通过redux将整个利用状态存储到store中,组件能够派发dispatch行为action给store,其余组件通过订阅store中的状态state来更新本身的视图

点击如何应用和我的项目构造划分查看详解

为什么 React Router 中应用 Switch 关键字 ?
因为router和switch对于路由的渲染策略不同,对router来说,如果有的链接既能够被路由A匹配,又能够被路由B匹配,那么Router会同时渲染它们
对于switch来说,它只会渲染符合条件的第一个门路,防止反复匹配