高頻react面試題及答案_第1頁(yè)
高頻react面試題及答案_第2頁(yè)
高頻react面試題及答案_第3頁(yè)
高頻react面試題及答案_第4頁(yè)
高頻react面試題及答案_第5頁(yè)
已閱讀5頁(yè),還剩19頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

高頻react面試題及答案1.類組件中setState是同步還是異步?為什么會(huì)有這樣的表現(xiàn)?在哪些情況下是同步的?setState在類組件中默認(rèn)表現(xiàn)為異步更新,這是React為了優(yōu)化性能做的批量更新策略。React會(huì)將多個(gè)setState調(diào)用合并為一次更新,減少重新渲染的次數(shù)。其異步性體現(xiàn)在:調(diào)用setState后無(wú)法立即獲取更新后的state值,需要通過(guò)回調(diào)函數(shù)(setState的第二個(gè)參數(shù))或componentDidUpdate生命周期來(lái)獲取最新狀態(tài)。但setState的“異步”并非絕對(duì),其行為依賴于調(diào)用它的上下文環(huán)境:在React管理的事件處理函數(shù)(如onClick、onChange)中,setState是異步的。因?yàn)镽eact會(huì)將事件處理內(nèi)的所有setState收集起來(lái),在事件結(jié)束時(shí)批量更新。在原生事件(如addEventListener綁定的事件)、setTimeout/setInterval、Promise回調(diào)等非React管理的上下文中,setState會(huì)表現(xiàn)為同步更新。因?yàn)檫@些場(chǎng)景中React無(wú)法感知到批量更新的時(shí)機(jī),會(huì)立即執(zhí)行更新邏輯。例如,在setTimeout中調(diào)用setState時(shí),由于定時(shí)器回調(diào)由瀏覽器的任務(wù)隊(duì)列管理,React無(wú)法在定時(shí)器回調(diào)執(zhí)行時(shí)合并更新,因此會(huì)立即觸發(fā)重新渲染,此時(shí)setState表現(xiàn)為同步。2.React生命周期函數(shù)的執(zhí)行順序是怎樣的?16.3版本后新增的getDerivedStateFromProps和getSnapshotBeforeUpdate有什么作用?經(jīng)典類組件(React16.3前)的生命周期分為掛載、更新、卸載三個(gè)階段:掛載階段:constructor→componentWillMount(已廢棄)→render→componentDidMount更新階段:componentWillReceiveProps(已廢棄)→shouldComponentUpdate→componentWillUpdate(已廢棄)→render→componentDidUpdate卸載階段:componentWillUnmountReact16.3引入Fiber架構(gòu)后,為了支持異步渲染(ConcurrentMode),廢棄了componentWillMount、componentWillReceiveProps、componentWillUpdate這三個(gè)“will”開頭的生命周期(標(biāo)記為UNSAFE_前綴),新增了getDerivedStateFromProps和getSnapshotBeforeUpdate:getDerivedStateFromProps(靜態(tài)方法):在組件掛載或更新時(shí),當(dāng)props變化時(shí)被調(diào)用。它接收當(dāng)前props和prevState,返回一個(gè)對(duì)象用于更新state,或返回null表示不更新。主要用于替代componentWillReceiveProps,避免因異步更新導(dǎo)致的副作用問(wèn)題。例如,當(dāng)父組件傳遞的props變化時(shí),需要根據(jù)新props更新組件內(nèi)部state的場(chǎng)景。getSnapshotBeforeUpdate(實(shí)例方法):在render之后、DOM更新之前被調(diào)用。它可以獲取更新前的DOM狀態(tài)(如滾動(dòng)位置),返回的快照值會(huì)作為參數(shù)傳遞給componentDidUpdate。典型用途是在列表項(xiàng)更新時(shí),保持滾動(dòng)位置不變:通過(guò)記錄更新前的滾動(dòng)高度,在componentDidUpdate中調(diào)整滾動(dòng)條位置。完整的新生命周期順序(掛載時(shí)):constructor→staticgetDerivedStateFromProps→render→componentDidMount更新時(shí)(props/state變化或forceUpdate):staticgetDerivedStateFromProps→shouldComponentUpdate→render→getSnapshotBeforeUpdate→componentDidUpdate3.函數(shù)組件中useState的setter函數(shù)是同步還是異步?與類組件的setState有何區(qū)別?useState的setter函數(shù)在行為上與類組件的setState類似,默認(rèn)表現(xiàn)為異步更新,但實(shí)現(xiàn)機(jī)制不同。在React事件處理或hooks回調(diào)中,setter函數(shù)不會(huì)立即更新state,而是將更新加入隊(duì)列,等待批量處理。例如,在點(diǎn)擊事件中連續(xù)調(diào)用兩次setCount(count+1),最終count只會(huì)增加1,因?yàn)閮纱胃禄谕粋€(gè)初始值。區(qū)別在于:類組件的setState可以接收對(duì)象或函數(shù)((prevState,props)=>newState),而useState的setter可以接收新值或函數(shù)((prev)=>new)。使用函數(shù)形式可以確保獲取到最新的state,避免閉包陷阱。例如,在異步回調(diào)中調(diào)用setter時(shí),函數(shù)形式能保證基于最新狀態(tài)計(jì)算。類組件的setState可能觸發(fā)組件更新(除非shouldComponentUpdate返回false),而函數(shù)組件中useState的更新總是會(huì)觸發(fā)重新渲染(除非組件被React.memo包裹且props未變化)。類組件的setState支持批量更新的范圍更廣(如同一事件內(nèi)的多個(gè)setState合并),而函數(shù)組件中若在同一個(gè)事件循環(huán)中多次調(diào)用不同useState的setter,React也會(huì)合并為一次渲染。4.React的虛擬DOM(VirtualDOM)是如何工作的?diff算法的核心規(guī)則是什么?虛擬DOM是真實(shí)DOM的輕量級(jí)JavaScript對(duì)象表示,包含標(biāo)簽名、屬性、子節(jié)點(diǎn)等信息。其核心作用是通過(guò)比較兩次渲染的虛擬DOM樹差異(diff),僅更新真實(shí)DOM中變化的部分,減少直接操作DOM的性能消耗(DOM操作成本遠(yuǎn)高于JS計(jì)算)。React的diff算法遵循以下核心規(guī)則以降低復(fù)雜度(時(shí)間復(fù)雜度從O(n3)優(yōu)化到O(n)):同級(jí)比較:只比較同一層級(jí)的節(jié)點(diǎn),不會(huì)跨層級(jí)移動(dòng)節(jié)點(diǎn)。若節(jié)點(diǎn)在不同層級(jí)出現(xiàn),會(huì)直接卸載舊節(jié)點(diǎn)并掛載新節(jié)點(diǎn)。鍵(key)優(yōu)化:對(duì)于列表項(xiàng),通過(guò)唯一key標(biāo)識(shí)節(jié)點(diǎn)。當(dāng)列表順序變化時(shí),React根據(jù)key匹配新舊節(jié)點(diǎn),避免重新創(chuàng)建未變化的節(jié)點(diǎn)。若未提供key,React默認(rèn)按索引匹配,可能導(dǎo)致錯(cuò)誤更新(如插入新項(xiàng)時(shí)后續(xù)項(xiàng)的索引變化,引發(fā)不必要的重新渲染)。類型判斷:當(dāng)節(jié)點(diǎn)類型(如div→p)或組件類型(如ComponentA→ComponentB)變化時(shí),React會(huì)卸載舊節(jié)點(diǎn)并掛載新節(jié)點(diǎn)。若類型相同,僅更新屬性和子節(jié)點(diǎn)。例如,當(dāng)列表項(xiàng)順序變化時(shí),正確的key可以讓React識(shí)別到節(jié)點(diǎn)只是位置變化,只需調(diào)整DOM位置;而無(wú)key時(shí),React會(huì)認(rèn)為每個(gè)索引對(duì)應(yīng)的節(jié)點(diǎn)都發(fā)生了變化,導(dǎo)致所有節(jié)點(diǎn)重新渲染。5.如何優(yōu)化React組件的性能?常見的優(yōu)化手段有哪些?React性能優(yōu)化的核心是減少不必要的重新渲染,主要手段包括:避免父組件狀態(tài)變化導(dǎo)致子組件不必要的渲染:類組件:使用PureComponent(淺比較props和state)或手動(dòng)實(shí)現(xiàn)shouldComponentUpdate(對(duì)比變化的屬性)。函數(shù)組件:使用React.memo包裹組件(淺比較props),配合useMemo緩存計(jì)算結(jié)果,useCallback緩存回調(diào)函數(shù)(避免父組件重新渲染時(shí)提供新的函數(shù)引用,導(dǎo)致子組件重新渲染)。優(yōu)化狀態(tài)管理:將狀態(tài)提升到最近的公共父組件,避免深層嵌套組件因上層狀態(tài)變化而重新渲染。使用狀態(tài)分片(如多個(gè)useState代替單個(gè)對(duì)象狀態(tài)),僅當(dāng)相關(guān)狀態(tài)變化時(shí)觸發(fā)渲染。減少渲染邏輯中的計(jì)算量:用useMemo緩存昂貴的計(jì)算結(jié)果(如列表過(guò)濾、數(shù)據(jù)格式化),僅當(dāng)依賴項(xiàng)變化時(shí)重新計(jì)算。避免在render函數(shù)中定義對(duì)象或函數(shù)(如onClick={()=>handleClick()}),這會(huì)導(dǎo)致每次渲染提供新的引用,觸發(fā)子組件重新渲染。使用React.lazy和Suspense實(shí)現(xiàn)代碼分割:對(duì)非首屏組件使用動(dòng)態(tài)導(dǎo)入(import()),配合Suspense顯示加載狀態(tài),減少首屏加載時(shí)間。利用Fiber架構(gòu)的特性:React18的ConcurrentMode(并發(fā)模式)通過(guò)優(yōu)先級(jí)調(diào)度,允許低優(yōu)先級(jí)任務(wù)(如非緊急UI更新)中斷,優(yōu)先處理高優(yōu)先級(jí)任務(wù)(如用戶輸入),提升響應(yīng)速度。避免直接操作真實(shí)DOM:盡量使用React的狀態(tài)管理來(lái)更新UI,減少手動(dòng)調(diào)用getElementById等原生DOM操作,因?yàn)檫@會(huì)繞過(guò)虛擬DOM的diff過(guò)程,可能導(dǎo)致狀態(tài)與DOM不同步。6.解釋React的事件機(jī)制。為什么說(shuō)React事件是合成事件?與原生事件有何區(qū)別?React事件是對(duì)原生DOM事件的封裝,稱為“合成事件”(SyntheticEvent)。它遵循W3C標(biāo)準(zhǔn),提供與原生事件相同的接口(如stopPropagation、preventDefault),但內(nèi)部實(shí)現(xiàn)不同:合成事件的特點(diǎn):事件委托:React不會(huì)為每個(gè)DOM元素單獨(dú)綁定事件監(jiān)聽器,而是將所有事件綁定到根DOM節(jié)點(diǎn)(如<divid="root">),通過(guò)事件冒泡機(jī)制統(tǒng)一處理。這樣可以減少內(nèi)存占用,提升性能。跨瀏覽器兼容:對(duì)不同瀏覽器的事件行為進(jìn)行標(biāo)準(zhǔn)化(如IE的event對(duì)象獲取方式),開發(fā)者無(wú)需處理瀏覽器差異。事件對(duì)象池化:合成事件對(duì)象(SyntheticEvent)會(huì)被復(fù)用,在事件處理函數(shù)執(zhí)行后,所有屬性會(huì)被置為null(或放回池中)。若需要異步訪問(wèn)事件對(duì)象,需調(diào)用event.persist()方法保留引用。與原生事件的區(qū)別:綁定方式:React事件使用駝峰命名(如onClick),原生事件使用全小寫(如onclick);React事件通過(guò)JSX屬性傳遞,原生事件通過(guò)addEventListener或DOM屬性綁定。事件傳播:React的事件冒泡機(jī)制在合成事件系統(tǒng)中完成,與原生事件的冒泡是兩個(gè)獨(dú)立的流程。例如,在React事件處理函數(shù)中調(diào)用event.stopPropagation()只會(huì)阻止合成事件的冒泡,不會(huì)影響原生事件的冒泡;若要同時(shí)阻止原生事件,需手動(dòng)調(diào)用event.nativeEvent.stopPropagation()。執(zhí)行順序:當(dāng)同一個(gè)DOM元素同時(shí)綁定React事件和原生事件時(shí),原生事件的監(jiān)聽器會(huì)先執(zhí)行,React合成事件后執(zhí)行(因?yàn)镽eact的事件委托是在原生事件冒泡到根節(jié)點(diǎn)時(shí)觸發(fā))。7.什么是Fiber架構(gòu)?它解決了什么問(wèn)題?核心設(shè)計(jì)思想是什么?Fiber是React16引入的新協(xié)調(diào)器(Reconciler)的底層數(shù)據(jù)結(jié)構(gòu),用于替代React15的StackReconciler。其核心目標(biāo)是解決復(fù)雜應(yīng)用中長(zhǎng)任務(wù)導(dǎo)致的頁(yè)面卡頓問(wèn)題(如JS執(zhí)行時(shí)間過(guò)長(zhǎng)阻塞UI渲染和用戶輸入)。StackReconciler的問(wèn)題:采用遞歸方式進(jìn)行虛擬DOM的diff計(jì)算,一旦開始就無(wú)法中斷。當(dāng)組件樹很深時(shí),遞歸調(diào)用??赡艹^(guò)16ms(瀏覽器一幀的時(shí)間),導(dǎo)致頁(yè)面掉幀,用戶體驗(yàn)卡頓。Fiber架構(gòu)的核心設(shè)計(jì)思想是“可中斷的協(xié)作式調(diào)度”:將調(diào)和(Reconciliation)過(guò)程拆分為多個(gè)小任務(wù)(work),每個(gè)任務(wù)執(zhí)行一段時(shí)間后(如5ms),主動(dòng)讓出JS執(zhí)行權(quán)給瀏覽器(通過(guò)requestIdleCallback或MessageChannel),優(yōu)先處理用戶輸入、動(dòng)畫等緊急任務(wù),之后再恢復(fù)未完成的任務(wù)。Fiber的實(shí)現(xiàn)基于“鏈表”結(jié)構(gòu):每個(gè)Fiber節(jié)點(diǎn)代表一個(gè)組件、DOM節(jié)點(diǎn)或其他類型的節(jié)點(diǎn),保存了組件的狀態(tài)、props、子節(jié)點(diǎn)等信息。通過(guò)child、sibling、return指針形成樹狀鏈表,使得調(diào)和過(guò)程可以從任意節(jié)點(diǎn)中斷和恢復(fù)。關(guān)鍵特性:任務(wù)優(yōu)先級(jí):每個(gè)任務(wù)被賦予不同優(yōu)先級(jí)(如用戶輸入觸發(fā)的更新優(yōu)先級(jí)高于數(shù)據(jù)加載),高優(yōu)先級(jí)任務(wù)可以中斷低優(yōu)先級(jí)任務(wù)。雙緩存機(jī)制:維護(hù)當(dāng)前渲染的Fiber樹(currenttree)和正在計(jì)算的Fiber樹(workInProgresstree),計(jì)算完成后通過(guò)替換根節(jié)點(diǎn)(commit階段)將workInProgress樹變?yōu)閏urrent樹,保證渲染的原子性。增量更新:將diff過(guò)程分解為多個(gè)步驟,逐步更新,避免長(zhǎng)時(shí)間阻塞主線程。8.useRef有哪些常見用途?與useState的區(qū)別是什么?useRef是React提供的一個(gè)hook,返回一個(gè)可變的ref對(duì)象,其current屬性可以保存任意值,且在組件生命周期內(nèi)保持引用不變。常見用途包括:訪問(wèn)DOM元素:通過(guò)ref屬性綁定到組件或DOM節(jié)點(diǎn),如constinputRef=useRef();<inputref={inputRef}/>,之后可通過(guò)inputRef.current獲取DOM節(jié)點(diǎn)。保存可變的狀態(tài):如定時(shí)器ID、第三方庫(kù)實(shí)例等需要在多次渲染間保持的非UI狀態(tài)。因?yàn)閡seState的更新會(huì)觸發(fā)重新渲染,而useRef的current屬性變化不會(huì)觸發(fā)渲染。解決閉包陷阱:在異步回調(diào)中獲取最新的state或props值。例如,在setTimeout中若直接使用舊的state,可通過(guò)ref保存最新值,回調(diào)中訪問(wèn)ref.current獲取最新狀態(tài)。與useState的區(qū)別:數(shù)據(jù)類型:useState保存的是響應(yīng)式狀態(tài)(state變化觸發(fā)重新渲染),而useRef保存的是非響應(yīng)式數(shù)據(jù)(current變化不觸發(fā)渲染)。更新方式:useState通過(guò)setter函數(shù)更新,而useRef直接修改current屬性(如ref.current=newValue)。用途:useState用于管理UI相關(guān)的狀態(tài)(如按鈕是否激活、列表數(shù)據(jù)),useRef用于管理與渲染無(wú)關(guān)的可變數(shù)據(jù)或DOM引用。9.React中如何實(shí)現(xiàn)跨組件通信?常見的解決方案有哪些?跨組件通信指非父子關(guān)系的組件(如兄弟、祖孫、跨層級(jí)組件)之間的狀態(tài)共享,常見方案包括:狀態(tài)提升(LiftingStateUp):將共享狀態(tài)提升到最近的公共父組件,通過(guò)props傳遞狀態(tài)和修改狀態(tài)的函數(shù)。適用于層級(jí)較淺的組件樹,如兄弟組件通信。例如,兄弟組件A和B需要同步輸入內(nèi)容,可將輸入值保存在父組件,通過(guò)onChange回調(diào)更新父組件狀態(tài),再傳遞給A和B。上下文(Context):使用React.createContext創(chuàng)建上下文對(duì)象,通過(guò)Provider組件傳遞狀態(tài),子組件通過(guò)useContext(函數(shù)組件)或Context.Consumer(類組件)獲取狀態(tài)。適用于深層嵌套組件的狀態(tài)共享(如主題、用戶登錄信息)。需注意:Context的更新會(huì)觸發(fā)所有消費(fèi)該Context的組件重新渲染,因此需合理設(shè)計(jì)Context的粒度(避免將頻繁變化的狀態(tài)放入同一個(gè)Context)。狀態(tài)管理庫(kù)(如Redux、MobX):適用于復(fù)雜應(yīng)用的全局狀態(tài)管理。Redux通過(guò)單一store保存狀態(tài),通過(guò)action觸發(fā)reducer更新狀態(tài),組件通過(guò)connect或useSelector獲取狀態(tài),useDispatch發(fā)送action。MobX通過(guò)可觀察(observable)狀態(tài)和觀察者(observer)組件實(shí)現(xiàn)自動(dòng)響應(yīng)。事件總線(EventBus):通過(guò)全局的事件訂閱/發(fā)布機(jī)制實(shí)現(xiàn)通信。例如,使用自定義的EventEmitter類,組件A發(fā)布事件,組件B訂閱事件并執(zhí)行回調(diào)。需注意內(nèi)存泄漏問(wèn)題(組件卸載時(shí)需取消訂閱)。第三方庫(kù)(如Zustand、Jotai):輕量級(jí)狀態(tài)管理庫(kù),適合中小型應(yīng)用。Zustand通過(guò)create函數(shù)創(chuàng)建store,組件通過(guò)useStore鉤子訂閱特定狀態(tài),僅當(dāng)訂閱的狀態(tài)變化時(shí)重新渲染。10.React18的新特性有哪些?ConcurrentMode帶來(lái)了哪些改進(jìn)?React18的核心新特性包括:自動(dòng)批處理(AutomaticBatching):在更多場(chǎng)景下自動(dòng)合并狀態(tài)更新(如Promise、setTimeout、原生事件回調(diào)),減少不必要的重新渲染。例如,在Promise的then回調(diào)中調(diào)用多個(gè)setState,React會(huì)合并為一次渲染(React18前需手動(dòng)用flushSync包裹)。新的rootAPI:使用createRoot替代ReactDOM.render(如constroot=createRoot(container);root.render(<App/>)),支持并發(fā)特性。并發(fā)渲染(ConcurrentRendering):基于Fiber架構(gòu)的ConcurrentMode成為默認(rèn)模式,允許組件樹的不同部分以不同優(yōu)先級(jí)渲染。關(guān)鍵特性包括:SuspenseforDataFetching:支持在數(shù)據(jù)加載時(shí)顯示加載狀態(tài)(如<Suspensefallback={<Loading/>}><Component/></Suspense>),并允許組件樹的一部分先渲染,其他部分在數(shù)據(jù)準(zhǔn)備好后逐步加載。過(guò)渡(Transitions):通過(guò)useTransition或startTransition標(biāo)記非緊急更新(如搜索結(jié)果過(guò)濾),允許高優(yōu)先級(jí)任務(wù)(如用戶輸入)中斷低優(yōu)先級(jí)的過(guò)渡更新,避免界面卡頓。例如:const[isPending,startTransition]=useTransition();startTransition(()=>{setSearchQuery(inputValue);//低優(yōu)先級(jí)更新});流式服務(wù)端渲染(StreamingSSR):服務(wù)端可以逐步發(fā)送HTML片段,配合客戶端的hydration(水合),提升首屏加載速度。新的hooks:useId:提供全局唯一的ID,適用于服務(wù)端渲染場(chǎng)景(避免客戶端和服務(wù)端ID不一致)。useSyncExternalStore:用于安全地訂閱外部狀態(tài)(如Reduxstore),解決并發(fā)模式下的hydration問(wèn)題。useInsertionEffect:主要用于CSS-in-JS庫(kù),在DOM插入前執(zhí)行副作用(如注入樣式),避免布局抖動(dòng)。ConcurrentMode的核心改進(jìn)是提升應(yīng)用的響應(yīng)性,通過(guò)優(yōu)先級(jí)調(diào)度和可中斷的渲染,確保用戶輸入、動(dòng)畫等關(guān)鍵任務(wù)優(yōu)先執(zhí)行,避免長(zhǎng)任務(wù)阻塞主線程。例如,用戶輸入時(shí),輸入處理的高優(yōu)先級(jí)任務(wù)可以中斷正在進(jìn)行的低優(yōu)先級(jí)渲染任務(wù),用戶不會(huì)感受到延遲;輸入完成后,被中斷的渲染任務(wù)繼續(xù)執(zhí)行,更新界面。11.什么是React的memoization?常用的memoization工具(如React.memo、useMemo、useCallback)有何區(qū)別?Memoization(記憶化)是一種緩存技術(shù),用于避免重復(fù)計(jì)算相同的輸入結(jié)果。在React中,主要用于避免組件或計(jì)算的不必要重新執(zhí)行。常用工具及區(qū)別:React.memo:高階組件,用于緩存函數(shù)組件的渲染結(jié)果。它淺比較前后兩次渲染的props,若props未變化則復(fù)用上次渲染結(jié)果,避免重新調(diào)用組件函數(shù)。默認(rèn)淺比較,可通過(guò)第二個(gè)參數(shù)自定義比較函數(shù)((prevProps,nextProps)=>boolean)。適用于純組件(渲染結(jié)果僅依賴props)。useMemo:hook,用于緩存計(jì)算結(jié)果。它接收一個(gè)計(jì)算函數(shù)和依賴數(shù)組,僅當(dāng)依賴項(xiàng)變化時(shí)重新計(jì)算。返回緩存的值。適用于緩存昂貴的計(jì)算(如列表排序、數(shù)據(jù)過(guò)濾),避免每次渲染都重新計(jì)算。useCallback:hook,用于緩存函數(shù)引用。它接收一個(gè)函數(shù)和依賴數(shù)組,僅當(dāng)依賴項(xiàng)變化時(shí)返回新的函數(shù)引用。適用于緩存?zhèn)鬟f給子組件的回調(diào)函數(shù),避免父組件重新渲染時(shí)提供新的函數(shù)引用,導(dǎo)致子組件(被React.memo包裹)不必要的重新渲染。三者的核心區(qū)別在于應(yīng)用場(chǎng)景:React.memo緩存組件渲染結(jié)果,useMemo緩存計(jì)算值,useCallback緩存函數(shù)引用。例如,當(dāng)父組件傳遞一個(gè)回調(diào)函數(shù)給子組件時(shí),若父組件重新渲染,未使用useCallback會(huì)導(dǎo)致回調(diào)函數(shù)引用變化,子組件即使props其他屬性未變也會(huì)重新渲染;使用useCallback后,只要依賴項(xiàng)未變,回調(diào)函數(shù)引用不變,子組件可跳過(guò)渲染。12.解釋React中的“key”屬性的作用。為什么推薦使用穩(wěn)定、唯一的key?key是React用于標(biāo)識(shí)列表項(xiàng)的特殊屬性,幫助React在diff過(guò)程中快速識(shí)別哪些項(xiàng)被添加、刪除或重新排序。其核心作用是:優(yōu)化diff算法:通過(guò)key匹配新舊虛擬DOM中的節(jié)點(diǎn),避免重新創(chuàng)建未變化的節(jié)點(diǎn),減少DOM操作。保持組件狀態(tài):當(dāng)列表項(xiàng)順序變化時(shí),React根據(jù)key關(guān)聯(lián)組件實(shí)例,確保組件的狀態(tài)(如輸入框內(nèi)容、滾動(dòng)位置)與正確的項(xiàng)綁定。推薦使用穩(wěn)定、唯一的key的原因:唯一性:確保每個(gè)兄弟節(jié)點(diǎn)的key不同,避免React無(wú)法正確識(shí)別節(jié)點(diǎn)(可能導(dǎo)致渲染錯(cuò)誤或狀態(tài)混亂)。穩(wěn)定性:避免使用索引(index)作為key(除非列表順序固定且不會(huì)增刪項(xiàng))。例如,當(dāng)列表插入新項(xiàng)時(shí),后續(xù)項(xiàng)的索引會(huì)變化,導(dǎo)致key變化,React會(huì)認(rèn)為這些項(xiàng)被替換,重新創(chuàng)建組件實(shí)例,丟失原有狀態(tài)。例如,以下列表使用索引作為key存在隱患:constlist=items.map((item,index)=><Itemkey={index}{...item}/>);當(dāng)在列表頭部插入新項(xiàng)時(shí),原第一項(xiàng)的索引從0變?yōu)?,React會(huì)認(rèn)為原第一項(xiàng)被刪除,新項(xiàng)插入,原第二項(xiàng)變?yōu)樾碌牡谝豁?xiàng)(索引0),導(dǎo)致組件狀態(tài)錯(cuò)誤關(guān)聯(lián)。正確做法是使用數(shù)據(jù)中唯一且穩(wěn)定的標(biāo)識(shí)符(如數(shù)據(jù)庫(kù)ID、UUID)作為key:constlist=items.map(item=><Itemkey={item.id}{...item}/>);13.函數(shù)組件中如何處理副作用?useEffect的依賴數(shù)組有什么作用?常見的誤用場(chǎng)景有哪些?副作用(SideEffects)指與渲染無(wú)關(guān)的操作,如數(shù)據(jù)獲取、事件監(jiān)聽、定時(shí)器、修改外部變量等。函數(shù)組件中通過(guò)useEffect處理副作用,其語(yǔ)法為useEffect(effect,dependencies)。依賴數(shù)組的作用是控制effect的執(zhí)行時(shí)機(jī):空數(shù)組([]):effect僅在組件掛載(首次渲染)后執(zhí)行,卸載時(shí)執(zhí)行清理函數(shù)(若effect返回函數(shù))。適用于只需要執(zhí)行一次的副作用(如初始化數(shù)據(jù)獲?。0蕾図?xiàng)([a,b]):effect在組件掛載后、依賴項(xiàng)(a或b)變化時(shí)執(zhí)行。適用于依賴props或state的副作用(如根據(jù)props.id獲取數(shù)據(jù))。無(wú)依賴數(shù)組(省略):effect在每次組件渲染后執(zhí)行。適用于需要實(shí)時(shí)響應(yīng)的副作用(如監(jiān)聽窗口大小變化)。常見誤用場(chǎng)景:遺漏必要的依賴項(xiàng):若effect中使用了組件狀態(tài)(state)、props或其他組件內(nèi)的變量,需將其加入依賴數(shù)組。否則,effect可能使用舊值,導(dǎo)致邏輯錯(cuò)誤。例如:functionComponent(){const[count,setCount]=useState(0);useEffect(()=>{consttimer=setInterval(()=>{setCount(count+1);//錯(cuò)誤:count是閉包中的舊值,每次interval回調(diào)使用初始的count=0},1000);return()=>clearInterval(timer);},[]);//缺少依賴count,導(dǎo)致timer中的count不更新}正確做法是使用函數(shù)形式的setCount(setCount(c=>c+1)),或在依賴數(shù)組中加入count(但會(huì)導(dǎo)致每次count變化時(shí)重新創(chuàng)建timer)。不必要的依賴項(xiàng):將穩(wěn)定的值(如不會(huì)變化的函數(shù)、對(duì)象)加入依賴數(shù)組,導(dǎo)致effect頻繁執(zhí)行。例如,若handleClick函數(shù)未使用任何組件狀態(tài)或props,可通過(guò)useCallback緩存,避免其引用變化觸發(fā)effect重新執(zhí)行。清理函數(shù)未正確處理:effect返回的清理函數(shù)應(yīng)取消未完成的異步操作(如abortcontroller取消fetch請(qǐng)求)、移除事件監(jiān)聽等,避免內(nèi)存泄漏。例如,若effect中訂閱了事件,未在清理函數(shù)中移除監(jiān)聽,組件卸載后事件仍會(huì)觸發(fā),導(dǎo)致錯(cuò)誤。14.React中如何實(shí)現(xiàn)服務(wù)端渲染(SSR)?與客戶端渲染(CSR)相比有什么優(yōu)勢(shì)

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論