React常用面試題分析
React中調(diào)用setState之后發(fā)生了什么事情?
- React會將當(dāng)前傳入的參數(shù)對象與組件當(dāng)前的狀態(tài)合并,然后觸發(fā)調(diào)和過程,在調(diào)和的過程中,React會以相對高效的方式根據(jù)新的狀態(tài)構(gòu)建React元素樹并且
重新渲染整個(gè)UI界面.- React得到的元素樹之后,React會自動(dòng)計(jì)算出新的樹與老的樹的節(jié)點(diǎn)的差異,然后根據(jù)
差異對界面進(jìn)行最小化的渲染,在React的差異算法中,React能夠精確的知道在哪些位置發(fā)生看改變以及應(yīng)該如何去改變,這樣就保證了UI是按需更新的而不是重新渲染整個(gè)界面.
React中Element與Component的區(qū)別?
- ReactElement是描述屏幕上所見的內(nèi)容的數(shù)據(jù)結(jié)構(gòu),是對于UI的對象的表述.典型的ReactElement就是利用JSX構(gòu)建的聲明式代碼片段,然后被轉(zhuǎn)化為createElement的調(diào)用組合.
- ReactComponent則是可以接收參數(shù)輸入并且返回某個(gè)ReactElement的函數(shù)或者類.
在什么情況下會優(yōu)先選擇使用ClassComponent而不是FunctionalComponent?
組件需要包含內(nèi)部狀態(tài)或者使用到生命周期函數(shù)的時(shí)候使用ClassComponent,否則使用函數(shù)式組件
React中的refs屬性的作用是什么?
Refs是React提供給我們安全的訪問DOM元素或者某個(gè)組件實(shí)例的句柄,我們可以為元素添加ref屬性然后在回調(diào)函數(shù)中接收該元素在DOM樹中的句柄,該值會作為回調(diào)函數(shù)的第一個(gè)參數(shù)的返回.
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域中包含了一個(gè)ref屬性,該屬性的聲明的回調(diào)函數(shù)會接收inout對應(yīng)的DOM元素,我們將其綁定到this指針以便在其他的類函數(shù)中使用,refs并不是類組件的專屬,函數(shù)式組件同樣可以利用閉包的方式暫時(shí)存儲其值.
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在操作列表中元素被修改,添加,或者刪除的輔助標(biāo)識.
render(){
return (
<ul>
{this.state.todoItems.map(({task,uid})=>{
return <li key={uid}>{task}</li>
})}
</ul>
)
}
在開發(fā)過程中,我們需要保證某個(gè)元素的key 在其同級元素中具有唯一性,在
ReactDiff算法中React會借助元素的Key值來判斷該元素是新創(chuàng)建的還是被移動(dòng)而來的元素,React會保存這個(gè)輔助狀態(tài),從而減少不必要的元素渲染.此外,React還需要借助Key值來判斷元素與本地狀態(tài)的關(guān)聯(lián)干洗,因此我們在開發(fā)中不可忽視Key值的使用.
如果你創(chuàng)建了類似于下面的 Twitter 元素,那么他相關(guān)的類定義是什么樣子的?
<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
}
回調(diào)渲染模式(Render Callback Pattern),在這種模式中,組件會接收某個(gè)函數(shù)作為子組件,然后在渲染函數(shù)中以props.children進(jìn)行調(diào)用.
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)
}
}
此模式的優(yōu)勢在于將父組件與子組件解耦,父組件可以直接訪問子組件的內(nèi)部狀態(tài)而不需要再通過Props傳遞,這樣父組件能夠更為方便地控制子組件展示的UI界面.如果將原本展示的Badge替換為Profile,可以方便的修改回調(diào)函數(shù)來實(shí)現(xiàn)
<Twitter username="chuhan">
{ (user) => user === null }
</Twitter>
(未完)