React面试题及答案文档格式.docx
《React面试题及答案文档格式.docx》由会员分享,可在线阅读,更多相关《React面试题及答案文档格式.docx(11页珍藏版)》请在冰点文库上搜索。
ReactDiff算法中React会借助元素的Key值来判断该元素是新近创建的还是被移动而来的元素,从而减少不必要的元素重渲染。
此外,React还需要借助
Key值来判断元素与本地状态的关联关系,因此我们绝不可忽视转换函数中
Key的重要性。
5.React优势
1、React速度很快:
它并不直接对DOM进行操作,引入了一个叫做虚拟DOM
的概念,安插在javascript逻辑和实际的DOM之间,性能好。
2、跨浏览器兼容:
虚拟DOM帮助我们解决了跨浏览器问题,它为我们提供了标准化的API,甚至在IE8中都是没问题的。
3、一切都是component:
代码更加模块化,重用代码更容易,可维护性高。
4、单向数据流:
Flux是一个用于在JavaScript 应用中创建单向数据层的架构,它随着React视图库的开发而被Facebook概念化。
5、同构、纯粹的javascript:
因为搜索引擎的爬虫程序依赖的是服务端响应而不是JavaScript的执行,预渲染你的应用有助于搜索引擎优化。
6、兼容性好:
比如使用RequireJS来加载和打包,而Browserify 和Webpack
适用于构建大型应用。
它们使得那些艰难的任务不再让人望而生畏。
6.React很多个setState为什么是执行完再render7.reactdiff原理(常考,大厂必考)
把树形结构按照层级分解,只比较同级元素。
给列表结构的每个单元添加唯一的key属性,方便比较。
React只会匹配相同class的component(这里面的class指的是组件的名字)合并操作,调用component的setState方法的时候,React将其标记为
dirty.到每一个事件循环结束,React检查所有标记dirty的component重新绘制.
选择性子树渲染。
开发人员可以重写shouldComponentUpdate 提高diff的性能。
8.react生命周期函数
初始化阶段:
ogetDefaultProps:
获取实例的默认属性
ogetInitialState:
获取每个实例的初始化状态
ocomponentWillMount:
组件即将被装载、渲染到页面上
orender:
组件在这里生成虚拟的DOM节点
ocomponentDidMount:
组件真正在被装载之后运行中状态:
ocomponentWillReceiveProps:
组件将要接收到属性的时候调用
oshouldComponentUpdate:
组件接受到新属性或者新状态的时候
(可以返回false,接收数据后不更新,阻止render调用,后面的函数不会被继续执行了)
ocomponentWillUpdate:
组件即将更新不能修改属性和状态
组件重新描绘
ocomponentDidUpdate:
组件已经更新销毁阶段:
ocomponentWillUnmount:
组件即将销毁解析:
有三大阶段,每阶段的细分5-5-1
9.shouldComponentUpdate是做什么的?
(react性能优化是哪个周期函数?
shouldComponentUpdate 这个方法用来判断是否需要调用render方法重新描绘dom。
因为dom的描绘非常消耗性能,如果我们能在
shouldComponentUpdate 方法中能够写出更优化的domdiff算法,可以极大的提高性能。
10.为什么虚拟dom会提高性能?
(必考)
虚拟dom相当于在js和真实dom中间加了一个缓存,利用domdiff算法避免了没有必要的dom操作,从而提高性能。
用JavaScript对象结构表示DOM树的结构;
然后用这个树构建一个真正的
DOM树,插到文档当中当状态变更的时候,重新构造一棵新的对象树。
然后用新的树和旧的树进行比较,记录两棵树差异把2所记录的差异应用到步骤1
所构建的真正的DOM树上,视图就更新了。
11.React中refs的作用是什么?
Refs是React提供给我们的安全访问DOM元素或者某个组件实例的句柄。
我们可以为元素添加ref属性然后在回调函数中接受该元素在DOM树中的句柄,该值会作为回调函数的第一个参数返回:
classCustomFormextendsComponent{handleSubmit=() =>
{
console.log("
InputValue:
"
this.input.value);
};
formonSubmit={this.handleSubmit}>
inputtype="
text"
ref={input=>
(this.input=input)} />
buttontype="
submit"
>
Submit<
/button>
/form>
);
上述代码中的input域包含了一个ref属性,该属性声明的回调函数会接收
input对应的DOM元素,我们将其绑定到this指针以便在其他的类函数中使
用。
另外值得一提的是,refs并不是类组件的专属,函数式组件同样能够利用闭包暂存其值:
functionCustomForm({handleSubmit}){letinputElement;
return(
formonSubmit={()=>
handleSubmit(inputElement.value)}>
(inputElement =input)} />
12.setState和replaceState的区别
setState是修改其中的部分状态,相当于Object.assign,只是覆盖,不会减少原来的状态
replaceState是完全替换原来的状态,相当于赋值,将原来的state替换为另一个对象,如果新状态属性减少,那么state中就没有这个状态了
13.redux有什么缺点
一个组件所需要的数据,必须由父组件传过来,而不能像flux中直接从
store取。
当一个组件相关数据更新时,即使父组件不需要用到这个组件,父组件还是会重新render,可能会有效率影响,或者需要写复杂的
shouldComponentUpdate 进行判断。
14.简述flux思想
Flux的最大特点,就是数据的"
单向流动"
。
1.用户访问View
2.View发出用户的Action
3.Dispatcher收到Action,要求Store进行相应的更新
4.Store更新后,发出一个"
change"
事件
5.View收到"
事件后,更新页面
15.了解redux么,说一下redux吧
redux是一个应用数据流框架,主要是解决了组件间状态共享的问题,原理是集中式管理,主要有三个核心方法,action,store,reducer,工作流程是view调用store的dispatch接收action传入store,reducer进行state操作,view通过store提供的getState获取最新的数据,
flux也是用来进行数据操作的,有四个组成部分action,dispatch,view,
store,工作流程是view发出一个action,派发器接收action,让store
进行数据更新,更新完成以后store发出change,view接受change
更新视图。
Redux和Flux很像。
主要区别在于Flux有多个可以改变应用状态的store,在Flux中dispatcher被用来传递数据到注册的回调事件,但是在redux中只能定义一个可更新状态的store,redux把
store和Dispatcher合并,结构更加简单清晰
新增state,对状态的管理更加明确,通过redux,流程更加规范了,减少
手动编码量,提高了编码效率,同时缺点时当数据更新时有时候组件不需要,但是也要重新绘制,有些影响效率。
一般情况下,我们在构建多交互,多数据流的复杂项目应用时才会使用它们
16.React中有三种构建组件的方式React.createClass()、ES6class和无状态函数。
17.react组件的划分业务组件技术组件?
根据组件的职责通常把组件分为UI组件和容器组件。
UI组件负责UI的呈现,容器组件负责管理数据和逻辑。
两者通过React-Redux提供connect方法联系起来。
18.描述事件在React中的处理方式
为了解决跨浏览器兼容性问题,您的React中的事件处理程序将传递
SyntheticEvent 的实例,它是React的浏览器本机事件的跨浏览器包装器。
这些SyntheticEvent 与您习惯的原生事件具有相同的接口,除了它们在所有浏
览器中都兼容。
有趣的是,React实际上并没有将事件附加到子节点本身。
React将使用单个事件监听器监听顶层的所有事件。
这对于性能是有好处的,这也意味着在更新DOM时,React不需要担心跟踪事件监听器。
19.应该在React组件的何处发起Ajax请求
在React组件中,应该在componentDidMount 中发起网络请求。
这个方法会在组件第一次“挂载”(被添加到DOM)时执行,在组件的生命周期中仅会执行一次。
更重要的是,你不能保证在组件挂载之前Ajax请求已经完成,如果是这样,也就意味着你将尝试在一个未挂载的组件上调用setState,这将不起作用。
在componentDidMount 中发起网络请求将保证这有一个组件可以更新了。
20.(在构造函数中)调用super(props)的目的是什么
在super()被调用之前,子类是不能使用this的,在ES2015中,子类必须在
constructor中调用super()。
传递props给super()的原因则是便于(在子类中)能在constructor 访问this.props。
21.除了在构造函数中绑定this,还有其它方式吗
你可以使用属性初始值设定项(propertyinitializers)来正确绑定回调,
create-react-app也是默认支持的。
在回调中你可以使用箭头函数,但问题是每次组件渲染时都会创建一个新的回调。
22.为什么建议传递给setState的参数是一个callback而不是一个对象
因为this.props和this.state的更新可能是异步的,不能依赖它们的值去计算下一个state。
23.何为高阶组件(higherordercomponent)
高阶组件是一个以组件为参数并返回一个新组件的函数。
HOC运行你重用代码、逻辑和引导抽象。
最常见的可能是Redux的connect函数。
除了简单分享工具库和简单的组合,HOC最好的方式是共享React组件之间的行为。
如果
你发现你在不同的地方写了大量代码来做同一件事时,就应该考虑将代码重构为可重用的HOC。
24.何为受控组件(controlledcomponent)
在HTML中,类似<
input>
<
textarea>
和<
select>
这样的表单元素会维护自身的状态,并基于用户的输入来更新。
当用户提交表单时,前面提到的元素的值将随表单一起被发送。
但在React中会有些不同,包含表单元素的组件将会在
state中追踪输入的值,并且每次调用回调函数时,如onChange会更新state,重新渲染组件。
一个输入表单元素,它的值通过React的这种方式来控制,这样的元素就被称为"
受控元素"
25.在React当中Element和Component有何区别?
ReactElement 是描述屏幕上所见内容的数据结构,是对于UI的对象表述。
典
型的ReactElement 就是利用JSX构建的声明式代码片然后被转化为
createElement的调用组合。
ReactComponent 是一个函数或一个类,可以接收参数输入,并且返回某个
ReactElement
26.(组件的)状态(state)和属性(props)之间有何区别
State是一种数据结构,用于组件挂载时所需数据的默认值。
State可能会随着时间的推移而发生突变,但多数时候是作为用户事件行为的结果。
Props(properties 的简写)则是组件的配置。
props由父组件传递给子组件,并且就子组件而言,props是不可变的(immutable)。
组件不能改变
自身的props,但是可以把其子组件的 props放在一起(统一管理)。
Props也不仅仅是数据--回调函数也可以通过props传递。
27.展示组件(Presentationalcomponent)和容器组件(Containercomponent)之间有何区别?
展示组件关心组件看起来是什么。
展示专门通过props接受数据和回调,并且几乎不会有自身的状态,但当展示组件拥有自身的状态时,通常也只关心UI状态而不是数据的状态。
容器组件则更关心组件是如何运作的。
容器组件会为展示组件或者其它容器组件提供数据和行为(behavior),它们会调用Fluxactions,并将其作
为回调提供给展示组件。
容器组件经常是有状态的,因为它们是(其它组件的)数据源。
28.类组件(Classcomponent)和函数式组件(Functionalcomponent)之间有何区别?
函数式组件比类组件操作简单,只是简单的调取和返回JSX;
而类组件可以使用生命周期函数来操作业务
函数式组件可以理解为静态组件(组件中的内容调取的时候已经固定了,很难再修改),而类组件,可以基于组件内部的状态来动态更新渲染的内容
类组件不仅允许你使用更多额外的功能,如组件自身的状态和生命周期钩子,也能使组件直接访问store并维持状态
当组件仅是接收props,并将组件自身渲染到页面时,该组件就是一个'
无状态组件(statelesscomponent)'
,可以使用一个纯函数来创建这样的组件。
这种组件也被称为哑组件(dumbcomponents)或展示组件
29.createElement和cloneElement有什么区别?
传入的第一个参数不同
React.createElement():
JSX 语法就是用React.createElement()来构建React元素的。
它接受三个参数,第一个参数可以是一个标签名。
如div、span,或者React
组件。
第二个参数为传入的属性。
第三个以及之后的参数,皆作为组件的子组件。
React.createElement(type,[props],[...children]);
React.cloneElement()与React.createElement()相似,不同的是它传入的第一个
参数是一个React元素,而不是标签名或组件。
新添加的属性会并入原有的属
性,传入到返回的新元素中,而旧的子元素将被替换。
将保留原始元素的键和引用。
React.cloneElement(element,[props],[...children]);