调用 setState 之后产生了什么
在代码中调用 setState 函数之后,React 会将传入的参数与之前的状态进行合并,而后触发所谓的和谐过程(Reconciliation)。通过和谐过程,React 会以绝对高效的形式依据新的状态构建 React 元素树并且着手从新渲染整个 UI 界面。在 React 失去元素树之后,React 会计算出新的树和老的树之间的差别,而后依据差别对界面进行最小化从新渲染。通过 diff 算法,React 可能准确制导哪些地位产生了扭转以及应该如何扭转,这就保障了按需更新,而不是全副从新渲染。
- 在 setState 的时候,React 会为以后节点创立一个 updateQueue 的更新列队。
- 而后会触发 reconciliation 过程,在这个过程中,会应用名为 Fiber 的调度算法,开始生成新的 Fiber 树, Fiber 算法的最大特点是能够做到异步可中断的执行。
- 而后 React Scheduler 会依据优先级高下,先执行优先级高的节点,具体是执行 doWork 办法。
- 在 doWork 办法中,React 会执行一遍 updateQueue 中的办法,以取得新的节点。而后比照新旧节点,为老节点打上 更新、插入、替换 等 Tag。
- 以后节点 doWork 实现后,会执行 performUnitOfWork 办法取得新节点,而后再反复下面的过程。
- 当所有节点都 doWork 实现后,会触发 commitRoot 办法,React 进入 commit 阶段。
- 在 commit 阶段中,React 会依据后面为各个节点打的 Tag,一次性更新整个 dom 元素
能够应用TypeScript写React利用吗?怎么操作?
(1)如果还未创立 Create React App 我的项目
- 间接创立一个具备 typescript 的 Create React App 我的项目:
npx create-react-app demo --typescript
(2)如果曾经创立了 Create React App 我的项目,须要将 typescript 引入到已有我的项目中
- 通过命令将 typescript 引入我的项目:
npm install --save typescript @types/node @types/react @types/react-dom @types/jest
- 将我的项目中任何 后缀名为 ‘.js’ 的 JavaScript 文件重命名为 TypeScript 文件即后缀名为 ‘.tsx’(例如 src/index.js 重命名为 src/index.tsx )
react 实现一个全局的 dialog
import React, { Component } from 'react';import { is, fromJS } from 'immutable';import ReactDOM from 'react-dom';import ReactCSSTransitionGroup from 'react-addons-css-transition-group';import './dialog.css';let defaultState = { alertStatus:false, alertTip:"提醒", closeDialog:function(){}, childs:''}class Dialog extends Component{ state = { ...defaultState }; // css动画组件设置为指标组件 FirstChild = props => { const childrenArray = React.Children.toArray(props.children); return childrenArray[0] || null; } //关上弹窗 open =(options)=>{ options = options || {}; options.alertStatus = true; var props = options.props || {}; var childs = this.renderChildren(props,options.childrens) || ''; console.log(childs); this.setState({ ...defaultState, ...options, childs }) } //敞开弹窗 close(){ this.state.closeDialog(); this.setState({ ...defaultState }) } renderChildren(props,childrens) { //遍历所有子组件 var childs = []; childrens = childrens || []; var ps = { ...props, //给子组件绑定props _close:this.close //给子组件也绑定一个敞开弹窗的事件 }; childrens.forEach((currentItem,index) => { childs.push(React.createElement( currentItem, { ...ps, key:index } )); }) return childs; } shouldComponentUpdate(nextProps, nextState){ return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState)) } render(){ return ( <ReactCSSTransitionGroup component={this.FirstChild} transitionName='hide' transitionEnterTimeout={300} transitionLeaveTimeout={300}> <div className="dialog-con" style={this.state.alertStatus? {display:'block'}:{display:'none'}}> {this.state.childs} </div> </ReactCSSTransitionGroup> ); }}let div = document.createElement('div');let props = { };document.body.appendChild(div);let Box = ReactD
子类:
//子类jsximport React, { Component } from 'react';class Child extends Component { constructor(props){ super(props); this.state = {date: new Date()}; } showValue=()=>{ this.props.showValue && this.props.showValue() } render() { return ( <div className="Child"> <div className="content"> Child <button onClick={this.showValue}>调用父的办法</button> </div> </div> ); }}export default Child;
css:
.dialog-con{ position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.3);}
class类的key改了,会产生什么,会执行哪些周期函数?
在开发过程中,咱们须要保障某个元素的 key 在其同级元素中具备唯一性。在 React Diff 算法中 React 会借助元素的 Key 值来判断该元素是早先创立的还是被挪动而来的元素,从而缩小不必要的元素重渲染。此外,React 还须要借助 Key 值来判断元素与本地状态的关联关系,因而咱们绝不可漠视转换函数中 Key 的重要性。
答:componentWillMount componentDidMount render
何为 redux
Redux 的根本思维是整个利用的 state 放弃在一个繁多的 store 中。store 就是一个简略的 javascript 对象,而扭转利用 state 的惟一形式是在利用中触发 actions,而后为这些 actions 编写 reducers 来批改 state。整个 state 转化是在 reducers 中实现,并且不应该有任何副作用。
指出(组件)生命周期办法的不同
componentWillMount
-- 多用于根组件中的应用程序配置componentDidMount
-- 在这能够实现所有没有 DOM 就不能做的所有配置,并开始获取所有你须要的数据;如果须要设置事件监听,也能够在这实现componentWillReceiveProps
-- 这个周期函数作用于特定的 prop 扭转导致的 state 转换shouldComponentUpdate
-- 如果你放心组件适度渲染,shouldComponentUpdate
是一个改善性能的中央,因为如果组件接管了新的prop
, 它能够阻止(组件)从新渲染。shouldComponentUpdate 应该返回一个布尔值来决定组件是否要从新渲染componentWillUpdate
-- 很少应用。它能够用于代替组件的componentWillReceiveProps
和shouldComponentUpdate
(但不能拜访之前的 props)componentDidUpdate
-- 罕用于更新 DOM,响应 prop 或 state 的扭转componentWillUnmount
-- 在这你能够勾销网络申请,或者移除所有与组件相干的事件监听器
参考 前端进阶面试题具体解答
何为 reducer
一个 reducer 是一个纯函数,该函数以先前的 state 和一个 action 作为参数,并返回下一个 state。
React中refs的作用是什么?有哪些利用场景?
Refs 提供了一种形式,用于拜访在 render 办法中创立的 React 元素或 DOM 节点。Refs 应该审慎应用,如下场景应用 Refs 比拟适宜:
- 解决焦点、文本抉择或者媒体的管制
- 触发必要的动画
- 集成第三方 DOM 库
Refs 是应用 React.createRef()
办法创立的,他通过 ref
属性附加到 React 元素上。要在整个组件中应用 Refs,须要将 ref
在构造函数中调配给其实例属性:
class MyComponent extends React.Component { constructor(props) { super(props) this.myRef = React.createRef() } render() { return <div ref={this.myRef} /> }}
因为函数组件没有实例,因而不能在函数组件上间接应用 ref
:
function MyFunctionalComponent() { return <input />;}class Parent extends React.Component { constructor(props) { super(props); this.textInput = React.createRef(); } render() { // 这将不会工作! return ( <MyFunctionalComponent ref={this.textInput} /> ); }}
但能够通过闭合的帮忙在函数组件外部进行应用 Refs:
function CustomTextInput(props) { // 这里必须申明 textInput,这样 ref 回调才能够援用它 let textInput = null; function handleClick() { textInput.focus(); } return ( <div> <input type="text" ref={(input) => { textInput = input; }} /> <input type="button" value="Focus the text input" onClick={handleClick} /> </div> ); }
留神:
- 不应该适度的应用 Refs
ref
的返回值取决于节点的类型:- 当
ref
属性被用于一个一般的 HTML 元素时,React.createRef()
将接管底层 DOM 元素作为他的current
属性以创立ref
。 - 当
ref
属性被用于一个自定义的类组件时,ref
对象将接管该组件已挂载的实例作为他的current
。
- 当
- 当在父组件中须要拜访子组件中的
ref
时可应用传递 Refs 或回调 Refs。
Component, Element, Instance 之间有什么区别和分割?
- 元素: 一个元素
element
是一个一般对象(plain object),形容了对于一个DOM节点或者其余组件component
,你想让它在屏幕上出现成什么样子。元素element
能够在它的属性props
中蕴含其余元素(译注:用于造成元素树)。创立一个React元素element
老本很低。元素element
创立之后是不可变的。 - 组件: 一个组件
component
能够通过多种形式申明。能够是带有一个render()
办法的类,简略点也能够定义为一个函数。这两种状况下,它都把属性props
作为输出,把返回的一棵元素树作为输入。 - 实例: 一个实例
instance
是你在所写的组件类component class
中应用关键字this
所指向的货色(译注:组件实例)。它用来存储本地状态和响应生命周期事件很有用。
函数式组件(Functional component
)基本没有实例instance
。类组件(Class component
)有实例instance
,然而永远也不须要间接创立一个组件的实例,因为React帮咱们做了这些。
在结构函数调用 super 并将 props 作为参数传入的作用
在调用 super() 办法之前,子类构造函数无奈应用this援用,ES6 子类也是如此。
将 props 参数传递给 super() 调用的次要起因是在子构造函数中可能通过this.props来获取传入的 props
传递了props
class MyComponent extends React.Component { constructor(props) { super(props); console.log(this.props); // { name: 'sudheer',age: 30 } }}
没传递 props
class MyComponent extends React.Component { constructor(props) { super(); console.log(this.props); // undefined // 然而 Props 参数依然可用 console.log(props); // Prints { name: 'sudheer',age: 30 } } render() { // 构造函数内部不受影响 console.log(this.props); // { name: 'sudheer',age: 30 } }}
react-router4的外围
- 路由变成了组件
- 扩散到各个页面,不须要配置 比方
<link> <route></route>
如何在React中应用innerHTML
减少dangerouslySetInnerHTML属性,并且传入对象的属性名叫\_html
function Component(props){ return <div dangerouslySetInnerHTML={{_html:'<span>你好</span>'}}> </div>}
展现组件(Presentational component)和容器组件(Container component)之间有何不同
展现组件关怀组件看起来是什么。展现专门通过 props 承受数据和回调,并且简直不会有本身的状态,但当展现组件领有本身的状态时,通常也只关怀 UI 状态而不是数据的状态。
容器组件则更关怀组件是如何运作的。容器组件会为展现组件或者其它容器组件提供数据和行为(behavior),它们会调用 Flux actions
,并将其作为回调提供给展现组件。容器组件常常是有状态的,因为它们是(其它组件的)数据源。
为什么要应用 React. Children. map( props. children,( )=>)而不是props. children. map ( ( ) => )?
因为不能保障 props. children将是一个数组。
以上面的代码为例。
<Parent> <h1>有课前端网</h1></Parent>
在父组件外部,如果尝试应用 props.children. map映射子对象,则会抛出谬误,因为props. children是一个对象,而不是一个数组。
如果有多个子元素, React会使 props.children成为一个数组,如下所示。
<Parent> <h1>有课前端网</h1> <h2>前端技术学习平台</h2></Parent>;//不倡议应用如下形式,在这个案例中会抛出谬误。class Parent extends Component { render() { return <div> {this.props.children.map((obj) => obj)}</div>; }}
倡议应用如下形式,防止在上一个案例中抛出谬误。
class Parent extends Component { render() { return <div> {React.Children.map(this.props.children, (obj) => obj)}</div>; }}
vue 或者react 优化整体优化
- 虚构dom
为什么虚构 dom 会进步性能?(必考)
虚构 dom 相当于在 js 和实在 dom 两头加了一个缓存,利用 dom diff 算法防止了没有必要的 dom 操作,从而进步性能。
用 JavaScript 对象构造示意 DOM 树的构造;而后用这个树构建一个真正的 DOM 树,插到文档当中当状态变更的时候,从新结构一棵新的对象树。而后用新的树和旧的树进行比拟,记录两棵树差别把 2 所记录的差别利用到步骤 1 所构建的真正的 DOM 树上,视图就更新了。
React的事件和一般的HTML事件有什么不同?
区别:
- 对于事件名称命名形式,原生事件为全小写,react 事件采纳小驼峰;
- 对于事件函数解决语法,原生事件为字符串,react 事件为函数;
- react 事件不能采纳 return false 的形式来阻止浏览器的默认行为,而必须要地明确地调用
preventDefault()
来阻止默认行为。
合成事件是 react 模仿原生 DOM 事件所有能力的一个事件对象,其长处如下:
- 兼容所有浏览器,更好的跨平台;
- 将事件对立寄存在一个数组,防止频繁的新增与删除(垃圾回收)。
- 不便 react 对立治理和事务机制。
事件的执行程序为原生事件先执行,合成事件后执行,合成事件会冒泡绑定到 document 上,所以尽量避免原生事件与合成事件混用,如果原生事件阻止冒泡,可能会导致合成事件不执行,因为须要冒泡到document 上合成事件才会执行。
react 强制刷新
component.forceUpdate() 一个不罕用的生命周期办法, 它的作用就是强制刷新
官网解释如下
默认状况下,当组件的 state 或 props 发生变化时,组件将从新渲染。如果 render() 办法依赖于其余数据,则能够调用 forceUpdate() 强制让组件从新渲染。
调用 forceUpdate() 将以致组件调用 render() 办法,此操作会跳过该组件的 shouldComponentUpdate()。但其子组件会触发失常的生命周期办法,包含 shouldComponentUpdate() 办法。如果标记发生变化,React 仍将只更新 DOM。
通常你应该防止应用 forceUpdate(),尽量在 render() 中应用 this.props 和 this.state。
shouldComponentUpdate 在初始化 和 forceUpdate 不会执行
ssr原理是什么?
外围原理其实就是借助虚构DOM来实现react代码可能在服务器运行的,node外面能够执行react代码
diff 算法?
- 把树形构造依照层级合成,只比拟同级元素
- 给列表构造的每个单元增加惟一的 key 属性,不便比拟
- React 只会匹配雷同 class 的 component(这外面的 class 指的是组件的名字)
- 合并操作,调用 component 的 setState 办法的时候, React 将其标记为 dirty.到每一个 事件循环完结, React 查看所有标记 dirty 的 component 从新绘制.
- 抉择性子树渲染。开发人员能够重写 shouldComponentUpdate 进步 diff 的性能。
React申明组件有哪几种办法,有什么不同?
React 申明组件的三种形式:
- 函数式定义的
无状态组件
- ES5原生形式
React.createClass
定义的组件 - ES6模式的
extends React.Component
定义的组件
(1)无状态函数式组件 它是为了创立纯展现组件,这种组件只负责依据传入的props来展现,不波及到state状态的操作
组件不会被实例化,整体渲染性能失去晋升,不能拜访this对象,不能拜访生命周期的办法
(2)ES5 原生形式 React.createClass // RFC React.createClass会自绑定函数办法,导致不必要的性能开销,减少代码过期的可能性。
(3)E6继承模式 React.Component // RCC 目前极为举荐的创立有状态组件的形式,最终会取代React.createClass模式;绝对于 React.createClass能够更好实现代码复用。
无状态组件绝对于于后者的区别: 与无状态组件相比,React.createClass和React.Component都是创立有状态的组件,这些组件是要被实例化的,并且能够拜访组件的生命周期办法。
React.createClass与React.Component区别:
① 函数this自绑定
- React.createClass创立的组件,其每一个成员函数的this都有React主动绑定,函数中的this会被正确设置。
- React.Component创立的组件,其成员函数不会主动绑定this,须要开发者手动绑定,否则this不能获取以后组件实例对象。
② 组件属性类型propTypes及其默认props属性defaultProps配置不同
- React.createClass在创立组件时,无关组件props的属性类型及组件默认的属性会作为组件实例的属性来配置,其中defaultProps是应用getDefaultProps的办法来获取默认组件属性的
- React.Component在创立组件时配置这两个对应信息时,他们是作为组件类的属性,不是组件实例的属性,也就是所谓的类的动态属性来配置的。
③ 组件初始状态state的配置不同
- React.createClass创立的组件,其状态state是通过getInitialState办法来配置组件相干的状态;
- React.Component创立的组件,其状态state是在constructor中像初始化组件属性一样申明的。