React常用面试题分析
React中调用setState之后发生了什么事情?
- React会将当前传入的参数对象与组件当前的状态合并,然后触发调和过程,在调和的过程中,React会以相对高效的方式根据新的状态构建React元素树并且
重新渲染整个UI界面
.- React得到的元素树之后,React会自动计算出新的树与老的树的节点的差异,然后根据
差异对界面进行最小化的渲染
,在React的差异算法中,React能够精确的知道在哪些位置发生看改变以及应该如何去改变,这样就保证了UI是按需更新的而不是重新渲染整个界面.
React中Element
与Component
的区别?
- ReactElement是描述屏幕上所见的内容的数据结构,是对于UI的对象的表述.典型的ReactElement就是利用JSX构建的声明式代码片段,然后被转化为createElement的调用组合.
- ReactComponent则是可以接收参数输入并且返回某个ReactElement的函数或者类.
在什么情况下会优先选择使用ClassComponent而不是FunctionalComponent?
组件需要包含内部状态或者使用到生命周期函数的时候使用ClassComponent,否则使用函数式组件
React中的refs属性的作用是什么?
Refs是React提供给我们安全的访问DOM元素或者某个组件实例的句柄,我们可以为元素添加ref属性然后在回调函数中接收该元素在DOM树中的句柄,该值会作为回调函数的第一个参数的返回.
class CustomerForm 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</botton>
</form>
)
}
}
Input域中包含了一个ref属性,该属性的声明的回调函数会接收inout对应的DOM元素,我们将其绑定到this指针以便在其他的类函数中使用,refs并不是类组件的专属,函数式组件同样可以利用闭包的方式暂时存储其值.
function CustomerForm(handleSubmit){
let inputElement ;
return (
<form onSubmit = {()=>handleSubmit(inputElement.value)}>
<input type='text' ref={(input) =>
inputElement = input
} />
<button type="submit">Submit</botton>
</form>
)
}
React中keys
的作用是什么?
Keys 是React在操作列表中元素被修改,添加,或者删除的辅助标识.
render(){
return (
<ul>
{this.state.todoItems.map(({task,uid})=>{
return <li key={uid}>{task}</li>
})}
</ul>
)
}
在开发过程中,我们需要保证某个元素的key 在其同级元素中具有唯一性,在
ReactDiff
算法中React
会借助元素的Key
值来判断该元素是新创建的还是被移动而来的元素,React会保存这个辅助状态,从而减少不必要的元素渲染.此外,React还需要借助Key
值来判断元素与本地状态的关联干洗,因此我们在开发中不可忽视Key
值的使用.
如果你创建了类似于下面的 Twitter 元素,那么他相关的类定义是什么样子的?
<Twitter username='chuhan'>
{(user)=> user === null ? <Loading /> : <Badage info = {user}>}
</Twitter>
import React,{Component,PropTypes} from 'react';
import fetchUser from 'Twitter';
class Twitter extends Component {
//todo something
}
回调渲染模式(Render Callback Pattern)
,在这种模式中,组件会接收某个函数作为子组件,然后在渲染函数中以props.children
进行调用.
import React ,{Component,PropTypes} from 'react';
import fetchUser from 'Twitter';
class Twitter extends Component{
state = {
user : null
}
satic propTypes = {
userName.propTypes.String.isRequied
}
componentDidMount(){
fetchUser(this.props.userName)
.then((user)=>{
this.setState({user})
})
}
render(){
return this.props.children(this.state.user)
}
}
此模式的优势在于将父组件与子组件解耦,父组件可以直接访问子组件的内部状态而不需要再通过Props
传递,这样父组件能够更为方便地控制子组件展示的UI界面.如果将原本展示的Badge
替换为Profile
,可以方便的修改回调函数来实现
<Twitter username="chuhan">
{ (user) => user === null }
</Twitter>
(未完)