1.React中key值的作用
key值的作用是给同级的元素添加一个唯一标识,因为在React diff算法中,是根据key值来判断元素是否是新增还是移动等等,减少了不必要的元素重渲染。React 还需要借助 Key 值来判断元素与本地状态的关联关系。
2.shouldComponentUpdate 是做什么的,(react 性能优化是哪个周期函数?)
shouldComponentUpdate 方法是用来判断render是否需要重新渲染DOM的,因为描绘DOM是非常耗性能的,所以能在这里生命周期里面写出优化的diff算法,就可以极大的提升性能。
3.为什么虚拟 dom 会提高性能?(必考)
虚拟DOM相当于是在js和真实DOM之中增加了一个缓存,利用dom diff算法避免了一些没有必要的dom操作,从而提升性能。
用JavaScript来表示一颗DOM树的话,相当于在第一次创建的时候,就创建好了一棵DOM数,当你状态发生改变时,会重新构造一棵虚拟DOM树来跟已经渲染好的真实DOM树进行对比,得出差异后再把记录的差异应用到真实的DOM树中,这样视图就更新了,也提高了性能。
4.react diff 原理(常考,大厂必考)
4.1 把树形结构按照层级来分,进行同级之间的比较。
4.2 给列表中的每个单元赋予一个key值,方便比较。
4.3 react只会匹配相同组件名字的component
4.4 合并操作,调用component的setState方法,react将其标记一下dirty,到所有的事件循环结束之
后,就会检查所有react所标记过的dirty的component,然后重新渲染。
4.5 选择性子树渲染,开发人员可以重写shouldComponentUpdate提高
5.React 中 refs 的作用是什么?
refs是React给我们提供的安全访问DOM元素或实例的方法,可以直接操控元素上有ref属性的DOM,方便开发。
6.类组件(class component)和函数式组件(function component)之间有何不同?
类组件允许你使用更多的功能,例如钩子函数,自身的状态,也能直接访问store仓库并维持状态。
如果组件仅仅接收props,并且将组件自身渲染到页面上时,该组件就是一个无状态组件,可以使用一个纯函数来创建这样的组件。
7.(组件的)状态(state)和属性(props)之间有何不同
state是一种数据结构,用于页面渲染时所使用的默认值,也是用户事件行为的结果。
props则是组件的配置,props由父传递给子组件,组件不能改变自身的props,但是可以把他的子组件的porps统一管理,props也可以传递回调函数。
8.受控组件和非受控组件(controlled component)
其值由React控制的输入表单元素称为“受控组件”。
受控组件有两个特点:
1.设置value值时,value由state控制。
2.value值一般在onchange事件中通过setState方法进行修改。
什么时候使用受控组件?
需要对组件的value值进行修改时,使用受控组件。比如:页面中有一个按钮,每点击一次按钮受控组件的值加1.
表单数据由 DOM 处理的组件叫做“非受控组件”。
非受控组件有两个特点:
- 不设置value值,
- 通过ref获取dom节点然后再取value值
<input type="text" placeholder="请输入姓名" name='username' ref={(input) => this.usernameElem = input}/>
取值方法:this.usernameElem.value
什么时候使用非受控组件?
任何时候都不需要改变组件的value值,这时候可以使用非受控组件。
9.高阶组件
高阶组件其实就是一个高阶函数。高阶函数的定义是接受函数作为参数的函数。如果曾经使用过类似 map 这样的函数,可能已经很熟悉高阶函数。如果不熟悉 map,它是一个数组遍历的方法,接受一个函数作为参数应用到数组中的每个元素。例如,可以像这样对一个数组作平方:
const square = (x) => x * x
[1, 2, 3].map(square)
//=> [ 1, 4, 9 ]
10.在构造函数中调用super(props)的目的是什么?
在super()被调用之前,子类是不能使用this的,在ES2015中,子类必须在constructor中调用super(),传递props给super()的原因是便于(在子类中)能在constructor访问this.props
11.在React组件的何处发起Ajax请求
应该在componentDidMount中发起网络请求。因为这个钩子函数会在DOM生成之后执行,在组件的生命周期中仅会执行一次。更重要的是,你不能保证在组件挂载之前Ajax请求完成,如果这样,你就意味着将一个未挂载的组件上调用setState方法,这将无效,所以在componentDidMount中发送请求可以保证组件可以更新。
12.描述事件在 React 中的处理方式。
为了解决跨浏览器兼容性问题,您的 React 中的事件处理程序将传递 SyntheticEvent 的实例,它是 React 的浏览器本机事件的跨浏览器包装器
13.createElement 和 cloneElement 有什么区别?
都是用来构建React元素的。
React.createElement() 接收三个参数,第一个参数可以是标签名,第二个参数为传入的属性,第三个以及之后的参数为组件的子组件。
React.cloneElement()与 React.createElement()相似,不同的是他传入的第一个参数是React元素,而不是标签名或者组件。
14.React 中有三种构建组件的方式
React.createClass()、ES6 class 和无状态函数。
15.react 组件的划分业务组件技术组件?
根据组件的职责通常把组件分为 UI 组件和容器组件。
UI 组件负责 UI 的呈现,容器组件负责管理数据和逻辑。
两者通过 React-Redux 提供 connect 方法联系起来。
16.简述flux思想
Flux的最大特点,就是数据的‘单向流动’。
用户访问view,view视图层发送用户的action,dispatch收到action之后,申请store进行更新,store更新后,发出一个‘change’事件,view收到‘change’事件之后事件发生改变。
17.React 项目用过什么脚手架(本题是开放性题目)
1.creat-react-app
2.Yeoman
3.UmiJS
4.Beatle
5.DvaJS
18.了解 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,流程更加规范了,减少手动编码量,提高了编码效率,同时缺点时当数据更新时有时候组件不需要,但是也要重新绘制,有些影响效率。一般情况下,我们在构建多交互,多数据流的复杂项目应用时才会使用它们
19.redux 有什么缺点
一个组件所需要的数据,必须由父组件传过来,而不能像 flux 中直接从 store 取。
当一个组件相关数据更新时,即使父组件不需要用到这个组件,父组件还是会重新 render,可能会有效率影响,或者需要写复杂的 shouldComponentUpdate 进行判断。
20.react-redux
提供两个对象(Connect,Provider),React-Redux 组件的作用是对 react 与 redux 进行连接,如果在 react 项目中直接使用 redux,那么需要把 redux 中的 store 数据,通过 props 属性,一层一层传递到组件中,这样做太麻烦了,所以可以借助 React-Redux 模块,可以跨层级的在任意组件中直接把 Redux 中的 store 数据取出来。