面試 React 框架八股文十問十答第五期
作者:程序員小白條,個人博客
相信看了本文后,對你的面試是有一定幫助的!關(guān)注專欄后就能收到持續(xù)更新!
?點(diǎn)贊?收藏?不迷路!?文章來源地址http://www.zghlxwxcb.cn/news/detail-802320.html
1)對 React context 的理解
React Context 是 React 中用于跨多層級傳遞數(shù)據(jù)的一種方式,可以讓組件之間共享一些全局的狀態(tài),而不需要通過一層層的手動傳遞 props。Context 提供了一個在組件樹中傳遞數(shù)據(jù)的方法,避免了 props 層層傳遞的繁瑣。
Context 主要包含兩部分:
-
React.createContext
: 創(chuàng)建一個 Context 對象,該對象包含了Provider
和Consumer
組件。 -
<MyContext.Provider>
: 在組件樹中的某個位置,用于提供共享的數(shù)據(jù),通過value
屬性傳遞數(shù)據(jù)。 -
<MyContext.Consumer>
: 在組件樹中的某個位置,用于訂閱Provider
提供的數(shù)據(jù)。
2)為什么React并不推薦優(yōu)先考慮使用Context?
盡管 React Context 提供了一種在組件之間共享狀態(tài)的方式,但并不是在所有情況下都建議優(yōu)先考慮使用 Context。以下是一些原因:
- 降低組件的可復(fù)用性: 使用 Context 可能使組件與特定的上下文綁定,導(dǎo)致組件在其他上下文中難以復(fù)用。
- 不容易追蹤數(shù)據(jù)流: 當(dāng)數(shù)據(jù)通過 Context 傳遞時,可能會變得不夠明確和難以追蹤。相比于顯式地通過 props 傳遞,Context 的數(shù)據(jù)流不夠明顯,可能使得代碼更難理解。
- 全局狀態(tài)管理庫更適用: 對于大型應(yīng)用,使用專門的全局狀態(tài)管理庫(如 Redux 或 MobX)可能更合適,因?yàn)樗鼈兲峁┝烁鼜?qiáng)大的狀態(tài)管理和調(diào)試工具。
雖然 Context 是一個強(qiáng)大的工具,但在一些場景下,更傳統(tǒng)的 props 傳遞仍然是更簡單、清晰、可維護(hù)的選擇。
3)React中什么是受控組件和非控組件?
-
受控組件(Controlled Components): 受控組件是指其狀態(tài)(如輸入框的值)完全受 React 控制的組件。通常,受控組件通過 props 接收其當(dāng)前值,并通過回調(diào)函數(shù)通知父組件狀態(tài)的變化。例如,
<input>
元素的值由 React 的狀態(tài)管理。class ControlledComponent extends React.Component { constructor(props) { super(props); this.state = { value: '' }; } handleChange = (event) => { this.setState({ value: event.target.value }); }; render() { return <input type="text" value={this.state.value} onChange={this.handleChange} />; } }
-
非控組件(Uncontrolled Components): 非控組件是指其狀態(tài)不受 React 管理,而是由 DOM 自身來處理。在非控組件中,狀態(tài)通常通過 DOM 的原生方式管理,而不是通過 React 的狀態(tài)。
class UncontrolledComponent extends React.Component { inputRef = React.createRef(); handleSubmit = () => { alert(`Input Value: ${this.inputRef.current.value}`); }; render() { return ( <div> <input type="text" ref={this.inputRef} /> <button onClick={this.handleSubmit}>Submit</button> </div> ); } }
在上述例子中,UncontrolledComponent
中的輸入框的值是由 DOM 自身管理的,而不是通過 React 的狀態(tài)管理。
4)React中refs的作用是什么?有哪些應(yīng)用場景?
Refs 是 React 提供的一種訪問 DOM 元素或類組件實(shí)例的方式。Refs 的主要作用是在 React 中訪問、操作和修改 DOM 元素,以及獲取或調(diào)用類組件的實(shí)例方法。
應(yīng)用場景包括:
-
訪問 DOM 元素: 使用
ref
屬性可以獲取組件渲染后對應(yīng)的 DOM 元素,從而進(jìn)行 DOM 操作。class MyComponent extends React.Component { constructor(props) { super(props); } componentDidMount() { // 訪問 DOM 元素 console.log(this.myRef.current); } render() { return <div ref={this.myRef}>Hello, World!</div>; } }
-
獲取或調(diào)用類組件的實(shí)例方法: 可以使用
ref
獲取類組件的實(shí)例,從而調(diào)用組件中的方法。class MyComponent extends React.Component { myMethod() { console.log('Method called'); } render() { return <div>Hello, World!</div>; } } class ParentComponent extends React.Component { constructor(props) { super(props); this.myComponentRef = React.createRef(); } componentDidMount() { // 獲取 MyComponent 的實(shí)例并調(diào)用方法 this.myComponentRef.current.myMethod(); } render() { return <MyComponent ref={this.myComponentRef} />; } }
5)React組件的構(gòu)造函數(shù)有什么作用?它是必須的嗎?
React 組件的構(gòu)造函數(shù) 是類組件中的一個特殊方法,它主要用于進(jìn)行初始化工作,設(shè)置初始狀態(tài)、綁定方法等。構(gòu)造函數(shù)是類組件的一部分,不是必須的,但在需要進(jìn)行一些初始化操作時是很有用的。
主要作用包括:
-
初始化狀態(tài)(state): 在構(gòu)造函數(shù)中可以使用
this.state
初始化組件的狀態(tài),為組件提供初始值。class MyComponent extends React.Component { constructor(props) { super(props); this.state = { count: 0 }; } // ... }
-
綁定方法: 在構(gòu)造函數(shù)中可以使用
bind
方法綁定事件處理函數(shù),確保它們在后
6)React.forwardRef是什么?它有什么作用?
React.forwardRef 是一個高階函數(shù),用于向子組件轉(zhuǎn)發(fā)父組件中的 ref。通過 forwardRef
,父組件可以直接訪問子組件的 DOM 節(jié)點(diǎn)或?qū)嵗?。這對于封裝組件并保持 ref 傳遞的純粹性非常有用。
const ChildComponent = React.forwardRef((props, ref) => {
return <input ref={ref} />;
});
const ParentComponent = () => {
const childRef = React.createRef();
return <ChildComponent ref={childRef} />;
};
在上面的例子中,ChildComponent
接收了 forwardRef
函數(shù),父組件 ParentComponent
可以通過 childRef
直接訪問 ChildComponent
內(nèi)部的 input
元素。
7)類組件與函數(shù)組件有什么異同?
類組件和函數(shù)組件都是 React 組件的兩種主要形式,它們有以下異同:
相同點(diǎn):
- 都可以用來定義 UI 組件。
- 可以擁有狀態(tài)(通過
useState
或this.state
)和生命周期方法(在類組件中)。
不同點(diǎn):
-
語法: 類組件是使用 ES6 類語法定義的,而函數(shù)組件是使用函數(shù)語法定義的。函數(shù)組件通常更簡潔。
// 類組件 class MyComponent extends React.Component { // ... } // 函數(shù)組件 function MyComponent() { // ... }
-
狀態(tài)管理: 類組件使用
this.state
來管理狀態(tài),而函數(shù)組件使用useState
鉤子。// 類組件 class MyComponent extends React.Component { constructor(props) { super(props); this.state = { count: 0 }; } // ... } // 函數(shù)組件 function MyComponent() { const [count, setCount] = React.useState(0); // ... }
-
生命周期: 類組件具有生命周期方法(如
componentDidMount
、componentDidUpdate
等),而函數(shù)組件可以使用useEffect
鉤子來模擬生命周期行為。
8)React setState 調(diào)用的原理
在 React 中,setState
是用于更新組件狀態(tài)的方法。調(diào)用 setState
會觸發(fā)一系列更新流程,其原理如下:
-
合并狀態(tài)(Merge State):
setState
可以接收一個對象或一個函數(shù)。當(dāng)接收一個對象時,React 會將該對象與當(dāng)前狀態(tài)進(jìn)行淺合并。如果接收一個函數(shù),該函數(shù)會接收先前的狀態(tài)和當(dāng)前的 props 作為參數(shù),然后返回一個新的狀態(tài)對象。// 對象形式 this.setState({ count: this.state.count + 1 }); // 函數(shù)形式 this.setState((prevState, props) => ({ count: prevState.count + 1 }));
-
觸發(fā)更新流程:
setState
調(diào)用會觸發(fā)組件的重新渲染。React 會通過調(diào)度機(jī)制將更新放入隊列中,然后在適當(dāng)?shù)臅r候執(zhí)行更新。 -
異步更新:
setState
并不會立即改變組件的狀態(tài),而是將更新放入隊列中。這是因?yàn)?React 會對一連串的setState
調(diào)用進(jìn)行合并,然后再進(jìn)行一次更新。這樣可以避免不必要的重復(fù)渲染。
9)React setState 調(diào)用之后發(fā)生了什么?是同步還是異步?
setState
調(diào)用之后,React 并不會立即執(zhí)行狀態(tài)更新,而是采用異步的方式進(jìn)行。這是因?yàn)?React 會將 setState
調(diào)用加入到隊列中,而不是立即執(zhí)行更新操作。
由于異步更新,連續(xù)多次調(diào)用 setState
不會立即觸發(fā)多次渲染,而是將這些調(diào)用合并成一次更新,以提高性能。
React 提供了一個 callback
參數(shù),可以在狀態(tài)更新完成并且組件重新渲染后執(zhí)行回調(diào)函數(shù)。這可以用于在狀態(tài)更新完成后執(zhí)行一些操作。
this.setState({ count: this.state.count + 1 }, () => {
console.log('State updated and component re-rendered.');
});
10)React中的setState批量更新的過程是什么?
React 中的 setState
批量更新是指在一個事件循環(huán)內(nèi)將多個 setState
調(diào)用合并成一次更新,以提高性能。這個過程可以分為以下幾個步驟:
-
觸發(fā)更新: 當(dāng)調(diào)用
setState
時,React 會將更新任務(wù)添加到隊列中,而不是立即執(zhí)行更新。 -
合并更新: React 會對隊列中的更新任務(wù)進(jìn)行合并,以減少重復(fù)渲染的次數(shù)。如果有多個
setState
調(diào)用,React 會將它們合并成一個更新任務(wù)。 - 異步更新: React 采用異步的方式執(zhí)行更新,即在當(dāng)前事件循環(huán)結(jié)束后再進(jìn)行更新。這樣可以確保在一次事件循環(huán)內(nèi)將所有更新任務(wù)合并并只觸發(fā)一次重新渲染。
-
生命周期方法調(diào)用: 如果組件在更新時有相關(guān)的生命周期方法(如
componentDidUpdate
),這些方法將在更新完成后被調(diào)用。
這個批量更新的過程使得 React 在性能上更高效,因?yàn)樗鼫p少了重復(fù)渲染的次數(shù)。但需要注意的是,并非所有情況都會觸發(fā)批量更新,例如在 setTimeout
、setInterval
、事件處理函數(shù)等異步場景中,setState
會以同步方式執(zhí)行,不會進(jìn)行批量更新。
開源項(xiàng)目地址:https://gitee.com/falle22222n-leaves/vue_-book-manage-system
已 300 + Star!文章來源:http://www.zghlxwxcb.cn/news/detail-802320.html
?點(diǎn)贊?收藏?不迷路!?
到了這里,關(guān)于面試 React 框架八股文十問十答第五期的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!