前端面試題必會(huì)之前端react面試題
React中有使用過getDefaultProps嗎?它有什么作用?
通過實(shí)現(xiàn)組件的getDefaultProps,對(duì)屬性設(shè)置默認(rèn)值(ES5的寫法):
var ShowTitle = React.createClass({ getDefaultProps:function(){ return{ title : "React" } }, render : function(){ return <h1>{this.props.title}</h1> } });
React.Component 和 React.PureComponent 的區(qū)別
PureComponent表示一個(gè)純組件,可以用來(lái)優(yōu)化React程序,減少render函數(shù)執(zhí)行的次數(shù),從而提高組件的性能。
在React中,當(dāng)prop或者state發(fā)生變化時(shí),可以通過在shouldComponentUpdate生命周期函數(shù)中執(zhí)行return false來(lái)阻止頁(yè)面的更新,從而減少不必要的render執(zhí)行。React.PureComponent會(huì)自動(dòng)執(zhí)行 shouldComponentUpdate。
不過,pureComponent中的 shouldComponentUpdate() 進(jìn)行的是淺比較,也就是說(shuō)如果是引用數(shù)據(jù)類型的數(shù)據(jù),只會(huì)比較不是同一個(gè)地址,而不會(huì)比較這個(gè)地址里面的數(shù)據(jù)是否一致。淺比較會(huì)忽略屬性和或狀態(tài)突變情況,其實(shí)也就是數(shù)據(jù)引用指針沒有變化,而數(shù)據(jù)發(fā)生改變的時(shí)候render是不會(huì)執(zhí)行的。如果需要重新渲染那么就需要重新開辟空間引用數(shù)據(jù)。PureComponent一般會(huì)用在一些純展示組件上。
使用pureComponent的好處:當(dāng)組件更新時(shí),如果組件的props或者state都沒有改變,render函數(shù)就不會(huì)觸發(fā)。省去虛擬DOM的生成和對(duì)比過程,達(dá)到提升性能的目的。這是因?yàn)閞eact自動(dòng)做了一層淺比較。
React 事件機(jī)制
<div onClick={this.handleClick.bind(this)}>點(diǎn)我</div>
React并不是將click事件綁定到了div的真實(shí)DOM上,而是在document處監(jiān)聽了所有的事件,當(dāng)事件發(fā)生并且冒泡到document處的時(shí)候,React將事件內(nèi)容封裝并交由真正的處理函數(shù)運(yùn)行。這樣的方式不僅僅減少了內(nèi)存的消耗,還能在組件掛在銷毀時(shí)統(tǒng)一訂閱和移除事件。
除此之外,冒泡到document上的事件也不是原生的瀏覽器事件,而是由react自己實(shí)現(xiàn)的合成事件(SyntheticEvent)。因此如果不想要是事件冒泡的話應(yīng)該調(diào)用event.preventDefault()方法,而不是調(diào)用event.stopProppagation()方法。 JSX 上寫的事件并沒有綁定在對(duì)應(yīng)的真實(shí) DOM 上,而是通過事件代理的方式,將所有的事件都統(tǒng)一綁定在了 document
上。這樣的方式不僅減少了內(nèi)存消耗,還能在組件掛載銷毀時(shí)統(tǒng)一訂閱和移除事件。
另外冒泡到 document
上的事件也不是原生瀏覽器事件,而是 React 自己實(shí)現(xiàn)的合成事件(SyntheticEvent)。因此我們?nèi)绻幌胍录芭莸脑?,調(diào)用 event.stopPropagation
是無(wú)效的,而應(yīng)該調(diào)用 event.preventDefault
。
實(shí)現(xiàn)合成事件的目的如下:
- 合成事件首先抹平了瀏覽器之間的兼容問題,另外這是一個(gè)跨瀏覽器原生事件包裝器,賦予了跨瀏覽器開發(fā)的能力;
- 對(duì)于原生瀏覽器事件來(lái)說(shuō),瀏覽器會(huì)給監(jiān)聽器創(chuàng)建一個(gè)事件對(duì)象。如果你有很多的事件監(jiān)聽,那么就需要分配很多的事件對(duì)象,造成高額的內(nèi)存分配問題。但是對(duì)于合成事件來(lái)說(shuō),有一個(gè)事件池專門來(lái)管理它們的創(chuàng)建和銷毀,當(dāng)事件需要被使用時(shí),就會(huì)從池子中復(fù)用對(duì)象,事件回調(diào)結(jié)束后,就會(huì)銷毀事件對(duì)象上的屬性,從而便于下次復(fù)用事件對(duì)象。
React 高階組件、Render props、hooks 有什么區(qū)別,為什么要不斷迭代
這三者是目前react解決代碼復(fù)用的主要方式:
- 高階組件(HOC)是 React 中用于復(fù)用組件邏輯的一種高級(jí)技巧。HOC 自身不是 React API 的一部分,它是一種基于 React 的組合特性而形成的設(shè)計(jì)模式。具體而言,高階組件是參數(shù)為組件,返回值為新組件的函數(shù)。
- render props是指一種在 React 組件之間使用一個(gè)值為函數(shù)的 prop 共享代碼的簡(jiǎn)單技術(shù),更具體的說(shuō),render prop 是一個(gè)用于告知組件需要渲染什么內(nèi)容的函數(shù) prop。
- 通常,render props 和高階組件只渲染一個(gè)子節(jié)點(diǎn)。讓 Hook 來(lái)服務(wù)這個(gè)使用場(chǎng)景更加簡(jiǎn)單。這兩種模式仍有用武之地,(例如,一個(gè)虛擬滾動(dòng)條組件或許會(huì)有一個(gè) renderltem 屬性,或是一個(gè)可見的容器組件或許會(huì)有它自己的 DOM 結(jié)構(gòu))。但在大部分場(chǎng)景下,Hook 足夠了,并且能夠幫助減少嵌套。
(1)HOC 官方解釋∶
高階組件(HOC)是 React 中用于復(fù)用組件邏輯的一種高級(jí)技巧。HOC 自身不是 React API 的一部分,它是一種基于 React 的組合特性而形成的設(shè)計(jì)模式。
簡(jiǎn)言之,HOC是一種組件的設(shè)計(jì)模式,HOC接受一個(gè)組件和額外的參數(shù)(如果需要),返回一個(gè)新的組件。HOC 是純函數(shù),沒有副作用。
// hoc的定義 function withSubscription(WrappedComponent, selectData) { return class extends React.Component { constructor(props) { super(props); this.state = { data: selectData(DataSource, props) }; } // 一些通用的邏輯處理 render() { // ... 并使用新數(shù)據(jù)渲染被包裝的組件! return <WrappedComponent data={this.state.data} {...this.props} />; } }; // 使用 const BlogPostWithSubscription = withSubscription(BlogPost, (DataSource, props) => DataSource.getBlogPost(props.id));
HOC的優(yōu)缺點(diǎn)∶
- 優(yōu)點(diǎn)∶ 邏輯服用、不影響被包裹組件的內(nèi)部邏輯。
- 缺點(diǎn)∶ hoc傳遞給被包裹組件的props容易和被包裹后的組件重名,進(jìn)而被覆蓋
(2)Render props 官方解釋∶
"render prop"是指一種在 React 組件之間使用一個(gè)值為函數(shù)的 prop 共享代碼的簡(jiǎn)單技術(shù)
具有render prop 的組件接受一個(gè)返回React元素的函數(shù),將render的渲染邏輯注入到組件內(nèi)部。在這里,"render"的命名可以是任何其他有效的標(biāo)識(shí)符。
// DataProvider組件內(nèi)部的渲染邏輯如下 class DataProvider extends React.Components { state = { name: 'Tom' } render() { return ( <div> <p>共享數(shù)據(jù)組件自己內(nèi)部的渲染邏輯</p> { this.props.render(this.state) } </div> ); } } // 調(diào)用方式 <DataProvider render={data => ( <h1>Hello {data.name}</h1> )}/>
由此可以看到,render props的優(yōu)缺點(diǎn)也很明顯∶
- 優(yōu)點(diǎn):數(shù)據(jù)共享、代碼復(fù)用,將組件內(nèi)的state作為props傳遞給調(diào)用者,將渲染邏輯交給調(diào)用者。
- 缺點(diǎn):無(wú)法在 return 語(yǔ)句外訪問數(shù)據(jù)、嵌套寫法不夠優(yōu)雅
(3)Hooks 官方解釋∶
Hook是 React 16.8 的新增特性。它可以讓你在不編寫 class 的情況下使用 state 以及其他的 React 特性。通過自定義hook,可以復(fù)用代碼邏輯。
// 自定義一個(gè)獲取訂閱數(shù)據(jù)的hook function useSubscription() { const data = DataSource.getComments(); return [data]; } // function CommentList(props) { const {data} = props; const [subData] = useSubscription(); ... } // 使用 <CommentList data='hello' />
以上可以看出,hook解決了hoc的prop覆蓋的問題,同時(shí)使用的方式解決了render props的嵌套地獄的問題。hook的優(yōu)點(diǎn)如下∶
- 使用直觀;
- 解決hoc的prop 重名問題;
- 解決render props 因共享數(shù)據(jù) 而出現(xiàn)嵌套地獄的問題;
- 能在return之外使用數(shù)據(jù)的問題。
需要注意的是:hook只能在組件頂層使用,不可在分支語(yǔ)句中使用。、
React怎么做數(shù)據(jù)的檢查和變化
Model
改變之后(可能是調(diào)用了setState
),觸發(fā)了virtual dom
的更新,再用diff
算法來(lái)把virtual DOM
比較real DOM
,看看是哪個(gè)dom
節(jié)點(diǎn)更新了,再渲染real dom
React實(shí)現(xiàn)的移動(dòng)應(yīng)用中,如果出現(xiàn)卡頓,有哪些可以考慮的優(yōu)化方案
- 增加
shouldComponentUpdate
鉤子對(duì)新舊props
進(jìn)行比較,如果值相同則阻止更新,避免不必要的渲染,或者使用PureReactComponent
替代Component
,其內(nèi)部已經(jīng)封裝了shouldComponentUpdate
的淺比較邏輯 - 對(duì)于列表或其他結(jié)構(gòu)相同的節(jié)點(diǎn),為其中的每一項(xiàng)增加唯一
key
屬性,以方便React
的diff
算法中對(duì)該節(jié)點(diǎn)的復(fù)用,減少節(jié)點(diǎn)的創(chuàng)建和刪除操作 render
函數(shù)中減少類似onClick={() => {doSomething()}}
的寫法,每次調(diào)用render函數(shù)時(shí)均會(huì)創(chuàng)建一個(gè)新的函數(shù),即使內(nèi)容沒有發(fā)生任何變化,也會(huì)導(dǎo)致節(jié)點(diǎn)沒必要的重渲染,建議將函數(shù)保存在組件的成員對(duì)象中,這樣只會(huì)創(chuàng)建一次- 組件的
props
如果需要經(jīng)過一系列運(yùn)算后才能拿到最終結(jié)果,則可以考慮使用reselect
庫(kù)對(duì)結(jié)果進(jìn)行緩存,如果props值未發(fā)生變化,則結(jié)果直接從緩存中拿,避免高昂的運(yùn)算代價(jià) webpack-bundle-analyzer
分析當(dāng)前頁(yè)面的依賴包,是否存在不合理性,如果存在,找到優(yōu)化點(diǎn)并進(jìn)行優(yōu)化
在 React中元素( element)和組件( component)有什么區(qū)別?
簡(jiǎn)單地說(shuō),在 React中元素(虛擬DOM)描述了你在屏幕上看到的DOM元素。
換個(gè)說(shuō)法就是,在 React中元素是頁(yè)面中DOM元素的對(duì)象表示方式。在 React中組件是一個(gè)函數(shù)或一個(gè)類,它可以接受輸入并返回一個(gè)元素。
注意:工作中,為了提高開發(fā)效率,通常使用JSX語(yǔ)法表示 React元素(虛擬DOM)。在編譯的時(shí)候,把它轉(zhuǎn)化成一個(gè) React. createElement調(diào)用方法。
高階組件
高階函數(shù):如果一個(gè)函數(shù)接受一個(gè)或多個(gè)函數(shù)作為參數(shù)或者返回一個(gè)函數(shù)就可稱之為高階函數(shù)。
高階組件:如果一個(gè)函數(shù) 接受一個(gè)或多個(gè)組件作為參數(shù)并且返回一個(gè)組件 就可稱之為 高階組件。
react 中的高階組件
React 中的高階組件主要有兩種形式:屬性代理和反向繼承。
屬性代理 Proxy
- 操作
props
- 抽離
state
- 通過
ref
訪問到組件實(shí)例 - 用其他元素包裹傳入的組件
WrappedComponent
反向繼承
會(huì)發(fā)現(xiàn)其屬性代理和反向繼承的實(shí)現(xiàn)有些類似的地方,都是返回一個(gè)繼承了某個(gè)父類的子類,只不過屬性代理中繼承的是 React.Component
,反向繼承中繼承的是傳入的組件 WrappedComponent
。
反向繼承可以用來(lái)做什么:
1.操作 state
高階組件中可以讀取、編輯和刪除WrappedComponent
組件實(shí)例中的state
。甚至可以增加更多的state
項(xiàng),但是非常不建議這么做因?yàn)檫@可能會(huì)導(dǎo)致state
難以維護(hù)及管理。
function withLogging(WrappedComponent) { return class extends WrappedComponent { render() { return ( <div>; <h2>;Debugger Component Logging...<h2>; <p>;state:<p>; <pre>;{JSON.stringify(this.state, null, 4)}<pre>; <p>props:<p>; <pre>{JSON.stringify(this.props, null, 4)}<pre>; {super.render()} <div>; ); } }; }
2.渲染劫持(Render Highjacking)
條件渲染通過 props.isLoading 這個(gè)條件來(lái)判斷渲染哪個(gè)組件。
修改由 render() 輸出的 React 元素樹
為什么 React 元素有一個(gè) $$typeof 屬性
目的是為了防止 XSS 攻擊。因?yàn)?Synbol 無(wú)法被序列化,所以 React 可以通過有沒有 $$typeof 屬性來(lái)斷出當(dāng)前的 element 對(duì)象是從數(shù)據(jù)庫(kù)來(lái)的還是自己生成的。
- 如果沒有 $$typeof 這個(gè)屬性,react 會(huì)拒絕處理該元素。
- 在 React 的古老版本中,下面的寫法會(huì)出現(xiàn) XSS 攻擊:
// 服務(wù)端允許用戶存儲(chǔ) JSON let expectedTextButGotJSON = { type: 'div', props: { dangerouslySetInnerHTML: { __html: '/* 把你想的擱著 */' }, }, // ... }; let message = { text: expectedTextButGotJSON }; // React 0.13 中有風(fēng)險(xiǎn) <p> {message.text} </p>
react-router4的核心
- 路由變成了組件
- 分散到各個(gè)頁(yè)面,不需要配置 比如
<link> <route></route>
React 設(shè)計(jì)思路,它的理念是什么?
(1)編寫簡(jiǎn)單直觀的代碼
React最大的價(jià)值不是高性能的虛擬DOM、封裝的事件機(jī)制、服務(wù)器端渲染,而是聲明式的直觀的編碼方式。react文檔第一條就是聲明式,React 使創(chuàng)建交互式 UI 變得輕而易舉。為應(yīng)用的每一個(gè)狀態(tài)設(shè)計(jì)簡(jiǎn)潔的視圖,當(dāng)數(shù)據(jù)改變時(shí) React 能有效地更新并正確地渲染組件。 以聲明式編寫 UI,可以讓代碼更加可靠,且方便調(diào)試。
(2)簡(jiǎn)化可復(fù)用的組件
React框架里面使用了簡(jiǎn)化的組件模型,但更徹底地使用了組件化的概念。React將整個(gè)UI上的每一個(gè)功能模塊定義成組件,然后將小的組件通過組合或者嵌套的方式構(gòu)成更大的組件。React的組件具有如下的特性∶
- 可組合:簡(jiǎn)單組件可以組合為復(fù)雜的組件
- 可重用:每個(gè)組件都是獨(dú)立的,可以被多個(gè)組件使用
- 可維護(hù):和組件相關(guān)的邏輯和UI都封裝在了組件的內(nèi)部,方便維護(hù)
- 可測(cè)試:因?yàn)榻M件的獨(dú)立性,測(cè)試組件就變得方便很多。
(3) Virtual DOM
真實(shí)頁(yè)面對(duì)應(yīng)一個(gè) DOM 樹。在傳統(tǒng)頁(yè)面的開發(fā)模式中,每次需要更新頁(yè)面時(shí),都要手動(dòng)操作 DOM 來(lái)進(jìn)行更新。 DOM 操作非常昂貴。在前端開發(fā)中,性能消耗最大的就是 DOM 操作,而且這部分代碼會(huì)讓整體項(xiàng)目的代碼變得難 以維護(hù)。React 把真實(shí) DOM 樹轉(zhuǎn)換成 JavaScript 對(duì)象樹,也就是 Virtual DOM,每次數(shù)據(jù)更新后,重新計(jì)算 Virtual DOM,并和上一次生成的 Virtual DOM 做對(duì)比,對(duì)發(fā)生變化的部分做批量更新。React 也提供了直觀的 shouldComponentUpdate 生命周期回調(diào),來(lái)減少數(shù)據(jù)變化后不必要的 Virtual DOM 對(duì)比過程,以保證性能。
(4)函數(shù)式編程
React 把過去不斷重復(fù)構(gòu)建 UI 的過程抽象成了組件,且在給定參數(shù)的情況下約定渲染對(duì)應(yīng)的 UI 界面。React 能充分利用很多函數(shù)式方法去減少冗余代碼。此外,由于它本身就是簡(jiǎn)單函數(shù),所以易于測(cè)試。
(5)一次學(xué)習(xí),隨處編寫
無(wú)論現(xiàn)在正在使用什么技術(shù)棧,都可以隨時(shí)引入 React來(lái)開發(fā)新特性,而不需要重寫現(xiàn)有代碼。
React 還可以使用 Node 進(jìn)行服務(wù)器渲染,或使用 React Native 開發(fā)原生移動(dòng)應(yīng)用。因?yàn)?React 組件可以映射為對(duì)應(yīng)的原生控件。在輸出的時(shí)候,是輸出 Web DOM,還是 Android 控件,還是 iOS 控件,就由平臺(tái)本身決定了。所以,react很方便和其他平臺(tái)集成
react組件的劃分業(yè)務(wù)組件技術(shù)組件?
- 根據(jù)組件的職責(zé)通常把組件分為UI組件和容器組件。
- UI 組件負(fù)責(zé) UI 的呈現(xiàn),容器組件負(fù)責(zé)管理數(shù)據(jù)和邏輯。
- 兩者通過
React-Redux
提供connect
方法聯(lián)系起來(lái)
React中的setState和replaceState的區(qū)別是什么?
(1)setState() setState()用于設(shè)置狀態(tài)對(duì)象,其語(yǔ)法如下:
setState(object nextState[, function callback])
- nextState,將要設(shè)置的新狀態(tài),該狀態(tài)會(huì)和當(dāng)前的state合并
- callback,可選參數(shù),回調(diào)函數(shù)。該函數(shù)會(huì)在setState設(shè)置成功,且組件重新渲染后調(diào)用。
合并nextState和當(dāng)前state,并重新渲染組件。setState是React事件處理函數(shù)中和請(qǐng)求回調(diào)函數(shù)中觸發(fā)UI更新的主要方法。
(2)replaceState() replaceState()方法與setState()類似,但是方法只會(huì)保留nextState中狀態(tài),原state不在nextState中的狀態(tài)都會(huì)被刪除。其語(yǔ)法如下:
replaceState(object nextState[, function callback])
- nextState,將要設(shè)置的新狀態(tài),該狀態(tài)會(huì)替換當(dāng)前的state。
- callback,可選參數(shù),回調(diào)函數(shù)。該函數(shù)會(huì)在replaceState設(shè)置成功,且組件重新渲染后調(diào)用。
總結(jié): setState 是修改其中的部分狀態(tài),相當(dāng)于 Object.assign,只是覆蓋,不會(huì)減少原來(lái)的狀態(tài)。而replaceState 是完全替換原來(lái)的狀態(tài),相當(dāng)于賦值,將原來(lái)的 state 替換為另一個(gè)對(duì)象,如果新狀態(tài)屬性減少,那么 state 中就沒有這個(gè)狀態(tài)了。
React 中的 useState()
是什么?
下面說(shuō)明useState(0)
的用途:
const [count, setCounter] = useState(0); const [moreStuff, setMoreStuff] = useState(); const setCount = () => { setCounter(count + 1); setMoreStuff(); };
useState
是一個(gè)內(nèi)置的 React Hook。useState(0)
返回一個(gè)元組,其中第一個(gè)參數(shù)count
是計(jì)數(shù)器的當(dāng)前狀態(tài),setCounter
提供更新計(jì)數(shù)器狀態(tài)的方法。
咱們可以在任何地方使用setCounter
方法更新計(jì)數(shù)狀態(tài)-在這種情況下,咱們?cè)?code>setCount函數(shù)內(nèi)部使用它可以做更多的事情,使用 Hooks,能夠使咱們的代碼保持更多功能,還可以避免過多使用基于類的組件。
react 的渲染過程中,兄弟節(jié)點(diǎn)之間是怎么處理的?也就是key值不一樣的時(shí)候
通常我們輸出節(jié)點(diǎn)的時(shí)候都是map一個(gè)數(shù)組然后返回一個(gè)
ReactNode
,為了方便react
內(nèi)部進(jìn)行優(yōu)化,我們必須給每一個(gè)reactNode
添加key
,這個(gè)key prop
在設(shè)計(jì)值處不是給開發(fā)者用的,而是給react用的,大概的作用就是給每一個(gè)reactNode
添加一個(gè)身份標(biāo)識(shí),方便react進(jìn)行識(shí)別,在重渲染過程中,如果key一樣,若組件屬性有所變化,則react
只更新組件對(duì)應(yīng)的屬性;沒有變化則不更新,如果key不一樣,則react先銷毀該組件,然后重新創(chuàng)建該組件
React中怎么檢驗(yàn)props?驗(yàn)證props的目的是什么?
React為我們提供了PropTypes以供驗(yàn)證使用。當(dāng)我們向Props傳入的數(shù)據(jù)無(wú)效(向Props傳入的數(shù)據(jù)類型和驗(yàn)證的數(shù)據(jù)類型不符)就會(huì)在控制臺(tái)發(fā)出警告信息。它可以避免隨著應(yīng)用越來(lái)越復(fù)雜從而出現(xiàn)的問題。并且,它還可以讓程序變得更易讀。
import PropTypes from 'prop-types'; class Greeting extends React.Component { render() { return ( <h1>Hello, {this.props.name}</h1> ); } } Greeting.propTypes = { name: PropTypes.string };
當(dāng)然,如果項(xiàng)目匯中使用了TypeScript,那么就可以不用PropTypes來(lái)校驗(yàn),而使用TypeScript定義接口來(lái)校驗(yàn)props。
什么是純函數(shù)?
純函數(shù)是不依賴并且不會(huì)在其作用域之外修改變量狀態(tài)的函數(shù)。本質(zhì)上,純函數(shù)始終在給定相同參數(shù)的情況下返回相同結(jié)果。
對(duì)有狀態(tài)組件和無(wú)狀態(tài)組件的理解及使用場(chǎng)景
(1)有狀態(tài)組件
特點(diǎn):
- 是類組件
- 有繼承
- 可以使用this
- 可以使用react的生命周期
- 使用較多,容易頻繁觸發(fā)生命周期鉤子函數(shù),影響性能
- 內(nèi)部使用 state,維護(hù)自身狀態(tài)的變化,有狀態(tài)組件根據(jù)外部組件傳入的 props 和自身的 state進(jìn)行渲染。
使用場(chǎng)景:
- 需要使用到狀態(tài)的。
- 需要使用狀態(tài)操作組件的(無(wú)狀態(tài)組件的也可以實(shí)現(xiàn)新版本react hooks也可實(shí)現(xiàn))
總結(jié): 類組件可以維護(hù)自身的狀態(tài)變量,即組件的 state ,類組件還有不同的生命周期方法,可以讓開發(fā)者能夠在組件的不同階段(掛載、更新、卸載),對(duì)組件做更多的控制。類組件則既可以充當(dāng)無(wú)狀態(tài)組件,也可以充當(dāng)有狀態(tài)組件。當(dāng)一個(gè)類組件不需要管理自身狀態(tài)時(shí),也可稱為無(wú)狀態(tài)組件。
(2)無(wú)狀態(tài)組件 特點(diǎn):
- 不依賴自身的狀態(tài)state
- 可以是類組件或者函數(shù)組件。
- 可以完全避免使用 this 關(guān)鍵字。(由于使用的是箭頭函數(shù)事件無(wú)需綁定)
- 有更高的性能。當(dāng)不需要使用生命周期鉤子時(shí),應(yīng)該首先使用無(wú)狀態(tài)函數(shù)組件
- 組件內(nèi)部不維護(hù) state ,只根據(jù)外部組件傳入的 props 進(jìn)行渲染的組件,當(dāng) props 改變時(shí),組件重新渲染。
使用場(chǎng)景:
- 組件不需要管理 state,純展示
優(yōu)點(diǎn):
- 簡(jiǎn)化代碼、專注于 render
- 組件不需要被實(shí)例化,無(wú)生命周期,提升性能。 輸出(渲染)只取決于輸入(屬性),無(wú)副作用
- 視圖和數(shù)據(jù)的解耦分離
缺點(diǎn):
- 無(wú)法使用 ref
- 無(wú)生命周期方法
- 無(wú)法控制組件的重渲染,因?yàn)闊o(wú)法使用shouldComponentUpdate 方法,當(dāng)組件接受到新的屬性時(shí)則會(huì)重渲染
總結(jié): 組件內(nèi)部狀態(tài)且與外部無(wú)關(guān)的組件,可以考慮用狀態(tài)組件,這樣狀態(tài)樹就不會(huì)過于復(fù)雜,易于理解和管理。當(dāng)一個(gè)組件不需要管理自身狀態(tài)時(shí),也就是無(wú)狀態(tài)組件,應(yīng)該優(yōu)先設(shè)計(jì)為函數(shù)組件。比如自定義的 <Button/>
、 <Input />
等組件。
React如何獲取組件對(duì)應(yīng)的DOM元素?
可以用ref來(lái)獲取某個(gè)子節(jié)點(diǎn)的實(shí)例,然后通過當(dāng)前class組件實(shí)例的一些特定屬性來(lái)直接獲取子節(jié)點(diǎn)實(shí)例。ref有三種實(shí)現(xiàn)方法:
字符串格式:字符串格式,這是React16版本之前用得最多的,例如:
<p ref="info">span</p>
函數(shù)格式:ref對(duì)應(yīng)一個(gè)方法,該方法有一個(gè)參數(shù),也就是對(duì)應(yīng)的節(jié)點(diǎn)實(shí)例,例如:
<p ref={ele => this.info = ele}></p>
createRef方法:React 16提供的一個(gè)API,使用React.createRef()來(lái)實(shí)現(xiàn)
React Portal 有哪些使用場(chǎng)景
- 在以前, react 中所有的組件都會(huì)位于 #app 下,而使用 Portals 提供了一種脫離 #app 的組件
- 因此 Portals 適合脫離文檔流(out of flow) 的組件,特別是 position: absolute 與 position: fixed的組件。比如模態(tài)框,通知,警告,goTop 等。
以下是官方一個(gè)模態(tài)框的示例,可以在以下地址中測(cè)試效果
<html> <body> <div id="app"></div> <div id="modal"></div> <div id="gotop"></div> <div id="alert"></div> </body> </html>
const modalRoot = document.getElementById('modal'); class Modal extends React.Component { constructor(props) { super(props); this.el = document.createElement('div'); } componentDidMount() { modalRoot.appendChild(this.el); } componentWillUnmount() { modalRoot.removeChild(this.el); } render() { return ReactDOM.createPortal( this.props.children, this.el, ); } }
React Hooks當(dāng)中的useEffect是如何區(qū)分生命周期鉤子的
useEffect可以看成是
componentDidMount
,componentDidUpdate
和componentWillUnmount
三者的結(jié)合。useEffect(callback, [source])接收兩個(gè)參數(shù),調(diào)用方式如下
useEffect(() => { console.log('mounted'); return () => { console.log('willUnmount'); } }, [source]);
生命周期函數(shù)的調(diào)用主要是通過第二個(gè)參數(shù)[source]來(lái)進(jìn)行控制,有如下幾種情況:
[source]
參數(shù)不傳時(shí),則每次都會(huì)優(yōu)先調(diào)用上次保存的函數(shù)中返回的那個(gè)函數(shù),然后再調(diào)用外部那個(gè)函數(shù);[source]
參數(shù)傳[]時(shí),則外部的函數(shù)只會(huì)在初始化時(shí)調(diào)用一次,返回的那個(gè)函數(shù)也只會(huì)最終在組件卸載時(shí)調(diào)用一次;[source]
參數(shù)有值時(shí),則只會(huì)監(jiān)聽到數(shù)組中的值發(fā)生變化后才優(yōu)先調(diào)用返回的那個(gè)函數(shù),再調(diào)用外部的函數(shù)。
到此這篇關(guān)于前端面試題之必會(huì)react面試題的文章就介紹到這了,更多相關(guān)前端react面試題內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
react-player實(shí)現(xiàn)視頻播放與自定義進(jìn)度條效果
本篇文章通過完整的代碼給大家介紹了react-player實(shí)現(xiàn)視頻播放與自定義進(jìn)度條效果,代碼簡(jiǎn)單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2022-01-01在React項(xiàng)目中實(shí)現(xiàn)一個(gè)簡(jiǎn)單的錨點(diǎn)目錄定位
錨點(diǎn)目錄定位功能在長(zhǎng)頁(yè)面和文檔類網(wǎng)站中非常常見,它可以讓用戶快速定位到頁(yè)面中的某個(gè)章節(jié),本文講給大家介紹一下React項(xiàng)目中如何實(shí)現(xiàn)一個(gè)簡(jiǎn)單的錨點(diǎn)目錄定位,文中有詳細(xì)的實(shí)現(xiàn)代碼,需要的朋友可以參考下2023-09-09React State狀態(tài)與生命周期的實(shí)現(xiàn)方法
這篇文章主要介紹了React State狀態(tài)與生命周期的實(shí)現(xiàn)方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03Next.js實(shí)現(xiàn)react服務(wù)器端渲染的方法示例
這篇文章主要介紹了Next.js實(shí)現(xiàn)react服務(wù)器端渲染的方法示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧2019-01-01解決react中useState狀態(tài)異步更新的問題
本文主要介紹了react中useState狀態(tài)異步更新的問題,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07React+EggJs實(shí)現(xiàn)斷點(diǎn)續(xù)傳的示例代碼
這篇文章主要介紹了React+EggJs實(shí)現(xiàn)斷點(diǎn)續(xù)傳的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07Mobx實(shí)現(xiàn)React?應(yīng)用的狀態(tài)管理詳解
這篇文章主要為大家介紹了Mobx?實(shí)現(xiàn)?React?應(yīng)用的狀態(tài)管理,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12