翻譯:瘋狂的技術宅
如果你是一位有抱負的前端程式設計師並準備面試,那麼這篇文章很適合你。本文是你學習和麵試 React 所需知識的完美指南。
JavaScript 工具緩慢而穩定地在市場中紮根,對 React 的需求呈指數級增長。選擇合適的技術來開發應用或網站變得越來越有挑戰性。其中 React 被認為是增長最快的 Javascript 框架。
截至今天,Github 上約有1,000名貢獻者。 Virtual DOM 和可重用元件等獨特功能吸引了前端開發人員的注意力。儘管它只是 MVC(模型 - 檢視 - 控制器)中“檢視”的庫,但它對 Angular,Meteor,Vue 等全面的框架也構成了強力的挑戰。下圖為流行的 JS 框架的趨勢:
JS 框架的趨勢React 面試題
以下是面試官最有可能問到的 50 個 React 面試題和答案。為方便你學習,我對它們進行了分類:
- 基本知識
- React 元件
- React Redux
- React 路由
基本知識
1. 區分Real DOM和Virtual DOM
Real DOM | Virtual DOM |
---|---|
1. 更新緩慢。 | 1. 更新更快。 |
2. 可以直接更新 HTML。 | 2. 無法直接更新 HTML。 |
3. 如果元素更新,則建立新DOM。 | 3. 如果元素更新,則更新 JSX 。 |
4. DOM操作代價很高。 | 4. DOM 操作非常簡單。 |
5. 消耗的記憶體較多。 | 5. 很少的記憶體消耗。 |
2. 什麼是React?
- React 是 Facebook 在 2011 年開發的前端 JavaScript 庫。
- 它遵循基於元件的方法,有助於構建可重用的UI元件。
- 它用於開發複雜和互動式的 Web 和移動 UI。
- 儘管它僅在 2015 年開源,但有一個很大的支援社群。
3. React有什麼特點?
React的主要功能如下:
- 它使用**虛擬DOM **而不是真正的DOM。
- 它可以用伺服器端渲染。
- 它遵循單向資料流或資料繫結。
4. 列出React的一些主要優點。
React的一些主要優點是:
- 它提高了應用的效能
- 可以方便地在客戶端和伺服器端使用
- 由於 JSX,程式碼的可讀性很好
- React 很容易與 Meteor,Angular 等其他框架整合
- 使用React,編寫UI測試用例變得非常容易
5. React有哪些限制?
React的限制如下:
- React 只是一個庫,而不是一個完整的框架
- 它的庫非常龐大,需要時間來理解
- 新手程式設計師可能很難理解
- 編碼變得複雜,因為它使用內聯模板和 JSX
6. 什麼是JSX?
JSX 是J avaScript XML 的簡寫。是 React 使用的一種檔案,它利用 JavaScript 的表現力和類似 HTML 的模板語法。這使得 HTML 檔案非常容易理解。此檔案能使應用非常可靠,並能夠提高其效能。下面是JSX的一個例子:
render(){
return(
<div>
<h1> Hello World from Edureka!!</h1>
</div>
);
}
複製程式碼
7. 你瞭解 Virtual DOM 嗎?解釋一下它的工作原理。
Virtual DOM 是一個輕量級的 JavaScript 物件,它最初只是 real DOM 的副本。它是一個節點樹,它將元素、它們的屬性和內容作為物件及其屬性。 React 的渲染函式從 React 元件中建立一個節點樹。然後它響應資料模型中的變化來更新該樹,該變化是由使用者或系統完成的各種動作引起的。
Virtual DOM 工作過程有三個簡單的步驟。
-
每當底層資料發生改變時,整個 UI 都將在 Virtual DOM 描述中重新渲染。
-
然後計算之前 DOM 表示與新表示的之間的差異。
-
完成計算後,將只用實際更改的內容更新 real DOM。
8. 為什麼瀏覽器無法讀取JSX?
瀏覽器只能處理 JavaScript 物件,而不能讀取常規 JavaScript 物件中的 JSX。所以為了使瀏覽器能夠讀取 JSX,首先,需要用像 Babel 這樣的 JSX 轉換器將 JSX 檔案轉換為 JavaScript 物件,然後再將其傳給瀏覽器。
9. 與 ES5 相比,React 的 ES6 語法有何不同?
以下語法是 ES5 與 ES6 中的區別:
- require 與 import
// ES5
var React = require('react');
// ES6
import React from 'react';
複製程式碼
- export 與 exports
// ES5
module.exports = Component;
// ES6
export default Component;
複製程式碼
- component 和 function
// ES5
var MyComponent = React.createClass({
render: function() {
return
<h3>Hello Edureka!</h3>;
}
});
// ES6
class MyComponent extends React.Component {
render() {
return
<h3>Hello Edureka!</h3>;
}
}
複製程式碼
- props
// ES5
var App = React.createClass({
propTypes: { name: React.PropTypes.string },
render: function() {
return
<h3>Hello, {this.props.name}!</h3>;
}
});
// ES6
class App extends React.Component {
render() {
return
<h3>Hello, {this.props.name}!</h3>;
}
}
複製程式碼
- state
// ES5
var App = React.createClass({
getInitialState: function() {
return { name: 'world' };
},
render: function() {
return
<h3>Hello, {this.state.name}!</h3>;
}
});
// ES6
class App extends React.Component {
constructor() {
super();
this.state = { name: 'world' };
}
render() {
return
<h3>Hello, {this.state.name}!</h3>;
}
}
複製程式碼
10. React與Angular有何不同?
主題 | React | Angular |
---|---|---|
1. 體系結構 | 只有 MVC 中的 View | 完整的 MVC |
2. 渲染 | 可以在伺服器端渲染 | 客戶端渲染 |
3. DOM | 使用 virtual DOM | 使用 real DOM |
4. 資料繫結 | 單向資料繫結 | 雙向資料繫結 |
5. 除錯 | 編譯時除錯 | 執行時除錯 |
6. 作者 |
React 元件
11. 你理解“在React中,一切都是元件”這句話。
元件是 React 應用 UI 的構建塊。這些元件將整個 UI 分成小的獨立並可重用的部分。每個元件彼此獨立,而不會影響 UI 的其餘部分。
12. 解釋 React 中 render() 的目的。
每個React元件強制要求必須有一個 render()。它返回一個 React 元素,是原生 DOM 元件的表示。如果需要渲染多個 HTML 元素,則必須將它們組合在一個封閉標記內,例如 <form>
、<group>
、<div>
等。此函式必須保持純淨,即必須每次呼叫時都返回相同的結果。
13. 如何將兩個或多個元件嵌入到一個元件中?
可以通過以下方式將元件嵌入到一個元件中:
class MyComponent extends React.Component{
render(){
return(
<div>
<h1>Hello</h1>
<Header/>
</div>
);
}
}
class Header extends React.Component{
render(){
return
<h1>Header Component</h1>
};
}
ReactDOM.render(
<MyComponent/>, document.getElementById('content')
);
複製程式碼
14. 什麼是 Props?
Props 是 React 中屬性的簡寫。它們是隻讀元件,必須保持純,即不可變。它們總是在整個應用中從父元件傳遞到子元件。子元件永遠不能將 prop 送回父元件。這有助於維護單向資料流,通常用於呈現動態生成的資料。
15. React中的狀態是什麼?它是如何使用的?
狀態是 React 元件的核心,是資料的來源,必須儘可能簡單。基本上狀態是確定元件呈現和行為的物件。與props 不同,它們是可變的,並建立動態和互動式元件。可以通過 this.state()
訪問它們。
16. 區分狀態和 props
條件 | State | Props |
---|---|---|
1. 從父元件中接收初始值 | Yes | Yes |
2. 父元件可以改變值 | No | Yes |
3. 在元件中設定預設值 | Yes | Yes |
4. 在元件的內部變化 | Yes | No |
5. 設定子元件的初始值 | Yes | Yes |
6. 在子元件的內部更改 | No | Yes |
17. 如何更新元件的狀態?
可以用 this.setState()
更新元件的狀態。
class MyComponent extends React.Component {
constructor() {
super();
this.state = {
name: 'Maxx',
id: '101'
}
}
render()
{
setTimeout(()=>{this.setState({name:'Jaeha', id:'222'})},2000)
return (
<div>
<h1>Hello {this.state.name}</h1>
<h2>Your Id is {this.state.id}</h2>
</div>
);
}
}
ReactDOM.render(
<MyComponent/>, document.getElementById('content')
);
複製程式碼
18. React 中的箭頭函式是什麼?怎麼用?
箭頭函式(=>)是用於編寫函式表示式的簡短語法。這些函式允許正確繫結元件的上下文,因為在 ES6 中預設下不能使用自動繫結。使用高階函式時,箭頭函式非常有用。
//General way
render() {
return(
<MyInput onChange = {this.handleChange.bind(this) } />
);
}
//With Arrow Function
render() {
return(
<MyInput onChange = { (e)=>this.handleOnChange(e) } />
);
}
複製程式碼
19. 區分有狀態和無狀態元件。
有狀態元件 | 無狀態元件 |
---|---|
1. 在記憶體中儲存有關元件狀態變化的資訊 | 1. 計算元件的內部的狀態 |
2. 有權改變狀態 | 2. 無權改變狀態 |
3. 包含過去、現在和未來可能的狀態變化情況 | 3. 不包含過去,現在和未來可能發生的狀態變化情況 |
4. 接受無狀態元件狀態變化要求的通知,然後將 props 傳送給他們。 | 4.從有狀態元件接收 props 並將其視為回撥函式。 |
20. React元件生命週期的階段是什麼?
React 元件的生命週期有三個不同的階段:
- *初始渲染階段:*這是元件即將開始其生命之旅並進入 DOM 的階段。
- *更新階段:*一旦元件被新增到 DOM,它只有在 prop 或狀態發生變化時才可能更新和重新渲染。這些只發生在這個階段。
- *解除安裝階段:*這是元件生命週期的最後階段,元件被銷燬並從 DOM 中刪除。
21. 詳細解釋 React 元件的生命週期方法。
一些最重要的生命週期方法是:
- componentWillMount**()** – 在渲染之前執行,在客戶端和伺服器端都會執行。
- componentDidMount**()** – 僅在第一次渲染後在客戶端執行。
- componentWillReceiveProps**()** – 當從父類接收到 props 並且在呼叫另一個渲染器之前呼叫。
- shouldComponentUpdate**()** – 根據特定條件返回 true 或 false。如果你希望更新元件,請返回true 否則返回 false。預設情況下,它返回 false。
- componentWillUpdate**()** – 在 DOM 中進行渲染之前呼叫。
- componentDidUpdate**()** – 在渲染髮生後立即呼叫。
- componentWillUnmount**()** – 從 DOM 解除安裝元件後呼叫。用於清理記憶體空間。
22. React中的事件是什麼?
在 React 中,事件是對滑鼠懸停、滑鼠單擊、按鍵等特定操作的觸發反應。處理這些事件類似於處理 DOM 元素中的事件。但是有一些語法差異,如:
- 用駝峰命名法對事件命名而不是僅使用小寫字母。
- 事件作為函式而不是字串傳遞。
事件引數重包含一組特定於事件的屬性。每個事件型別都包含自己的屬性和行為,只能通過其事件處理程式訪問。
23. 如何在React中建立一個事件?
class Display extends React.Component({
show(evt) {
// code
},
render() {
// Render the div with an onClick prop (value is a function)
return (
<div onClick={this.show}>Click Me!</div>
);
}
});
複製程式碼
24. React中的合成事件是什麼?
合成事件是圍繞瀏覽器原生事件充當跨瀏覽器包裝器的物件。它們將不同瀏覽器的行為合併為一個 API。這樣做是為了確保事件在不同瀏覽器中顯示一致的屬性。
25. 你對 React 的 refs 有什麼瞭解?
Refs 是 React 中引用的簡寫。它是一個有助於儲存對特定的 React 元素或元件的引用的屬性,它將由元件渲染配置函式返回。用於對 render() 返回的特定元素或元件的引用。當需要進行 DOM 測量或向元件新增方法時,它們會派上用場。
class ReferenceDemo extends React.Component{
display() {
const name = this.inputDemo.value;
document.getElementById('disp').innerHTML = name;
}
render() {
return(
<div>
Name: <input type="text" ref={input => this.inputDemo = input} />
<button name="Click" onClick={this.display}>Click</button>
<h2>Hello <span id="disp"></span> !!!</h2>
</div>
);
}
}
複製程式碼
26. 列出一些應該使用 Refs 的情況。
以下是應該使用 refs 的情況:
- 需要管理焦點、選擇文字或媒體播放時
- 觸發式動畫
- 與第三方 DOM 庫整合
27. 如何模組化 React 中的程式碼?
可以使用 export 和 import 屬性來模組化程式碼。它們有助於在不同的檔案中單獨編寫元件。
//ChildComponent.jsx
export default class ChildComponent extends React.Component {
render() {
return(
<div>
<h1>This is a child component</h1>
</div>
);
}
}
//ParentComponent.jsx
import ChildComponent from './childcomponent.js';
class ParentComponent extends React.Component {
render() {
return(
<div>
<App />
</div>
);
}
}
複製程式碼
28. 如何在 React 中建立表單
React 表單類似於 HTML 表單。但是在 React 中,狀態包含在元件的 state 屬性中,並且只能通過 setState()
更新。因此元素不能直接更新它們的狀態,它們的提交是由 JavaScript 函式處理的。此函式可以完全訪問使用者輸入到表單的資料。
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleSubmit} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
複製程式碼
29. 你對受控元件和非受控元件瞭解多少?
受控元件 | 非受控元件 |
---|---|
1. 沒有維持自己的狀態 | 1. 保持著自己的狀態 |
2.資料由父元件控制 | 2.資料由 DOM 控制 |
3. 通過 props 獲取當前值,然後通過回撥通知更改 | 3. Refs 用於獲取其當前值 |
30. 什麼是高階元件(HOC)?
高階元件是重用元件邏輯的高階方法,是一種源於 React 的元件模式。 HOC 是自定義元件,在它之內包含另一個元件。它們可以接受子元件提供的任何動態,但不會修改或複製其輸入元件中的任何行為。你可以認為 HOC 是“純(Pure)”元件。
31. 你能用HOC做什麼?
HOC可用於許多工,例如:
- 程式碼重用,邏輯和引導抽象
- 渲染劫持
- 狀態抽象和控制
- Props 控制
32. 什麼是純元件?
純(Pure) 元件是可以編寫的最簡單、最快的元件。它們可以替換任何只有 render() 的元件。這些元件增強了程式碼的簡單性和應用的效能。
33. React 中 key 的重要性是什麼?
key 用於識別唯一的 Virtual DOM 元素及其驅動 UI 的相應資料。它們通過回收 DOM 中當前所有的元素來幫助 React 優化渲染。這些 key 必須是唯一的數字或字串,React 只是重新排序元素而不是重新渲染它們。這可以提高應用程式的效能。
React Redux
34. MVC框架的主要問題是什麼?
以下是MVC框架的一些主要問題:
- 對 DOM 操作的代價非常高
- 程式執行緩慢且效率低下
- 記憶體浪費嚴重
- 由於迴圈依賴性,元件模型需要圍繞 models 和 views 進行建立
35. 解釋一下 Flux
Flux 是一種強制單向資料流的架構模式。它控制派生資料,並使用具有所有資料許可權的中心 store 實現多個元件之間的通訊。整個應用中的資料更新必須只能在此處進行。 Flux 為應用提供穩定性並減少執行時的錯誤。36. 什麼是Redux?
Redux 是當今最熱門的前端開發庫之一。它是 JavaScript 程式的可預測狀態容器,用於整個應用的狀態管理。使用 Redux 開發的應用易於測試,可以在不同環境中執行,並顯示一致的行為。
37. Redux遵循的三個原則是什麼?
- ***單一事實來源:***整個應用的狀態儲存在單個 store 中的物件/狀態樹裡。單一狀態樹可以更容易地跟蹤隨時間的變化,並除錯或檢查應用程式。
- ***狀態是隻讀的:***改變狀態的唯一方法是去觸發一個動作。動作是描述變化的普通 JS 物件。就像 state 是資料的最小表示一樣,該操作是對資料更改的最小表示。
- ***使用純函式進行更改:***為了指定狀態樹如何通過操作進行轉換,你需要純函式。純函式是那些返回值僅取決於其引數值的函式。
38. 你對“單一事實來源”有什麼理解?
Redux 使用 “Store” 將程式的整個狀態儲存在同一個地方。因此所有元件的狀態都儲存在 Store 中,並且它們從 Store 本身接收更新。單一狀態樹可以更容易地跟蹤隨時間的變化,並除錯或檢查程式。
39. 列出 Redux 的元件。
Redux 由以下元件組成:
- Action – 這是一個用來描述發生了什麼事情的物件。
- Reducer – 這是一個確定狀態將如何變化的地方。
- Store – 整個程式的狀態/物件樹儲存在Store中。
- View – 只顯示 Store 提供的資料。
40. 資料如何通過 Redux 流動?
41. 如何在 Redux 中定義 Action?
React 中的 Action 必須具有 type 屬性,該屬性指示正在執行的 ACTION 的型別。必須將它們定義為字串常量,並且還可以向其新增更多的屬性。在 Redux 中,action 被名為 Action Creators 的函式所建立。以下是 Action 和Action Creator 的示例:
function addTodo(text) {
return {
type: ADD_TODO,
text
}
}
複製程式碼
42. 解釋 Reducer 的作用。
Reducers 是純函式,它規定應用程式的狀態怎樣因響應 ACTION 而改變。Reducers 通過接受先前的狀態和 action 來工作,然後它返回一個新的狀態。它根據操作的型別確定需要執行哪種更新,然後返回新的值。如果不需要完成任務,它會返回原來的狀態。
43. Store 在 Redux 中的意義是什麼?
Store 是一個 JavaScript 物件,它可以儲存程式的狀態,並提供一些方法來訪問狀態、排程操作和註冊偵聽器。應用程式的整個狀態/物件樹儲存在單一儲存中。因此,Redux 非常簡單且是可預測的。我們可以將中介軟體傳遞到 store 來處理資料,並記錄改變儲存狀態的各種操作。所有操作都通過 reducer 返回一個新狀態。
44. Redux與Flux有何不同?
Flux | Redux |
---|---|
1. Store 包含狀態和更改邏輯 | 1. Store 和更改邏輯是分開的 |
2. 有多個 Store | 2. 只有一個 Store |
3. 所有 Store 都互不影響且是平級的 | 3. 帶有分層 reducer 的單一 Store |
4. 有單一排程器 | 4. 沒有排程器的概念 |
5. React 元件訂閱 store | 5. 容器元件是有聯絡的 |
6. 狀態是可變的 | 6. 狀態是不可改變的 |
45. Redux 有哪些優點?
Redux 的優點如下:
- 結果的可預測性 - 由於總是存在一個真實來源,即 store ,因此不存在如何將當前狀態與動作和應用的其他部分同步的問題。
- 可維護性 - 程式碼變得更容易維護,具有可預測的結果和嚴格的結構。
- 伺服器端渲染 - 你只需將伺服器上建立的 store 傳到客戶端即可。這對初始渲染非常有用,並且可以優化應用效能,從而提供更好的使用者體驗。
- 開發人員工具 - 從操作到狀態更改,開發人員可以實時跟蹤應用中發生的所有事情。
- 社群和生態系統 - Redux 背後有一個巨大的社群,這使得它更加迷人。一個由才華橫溢的人組成的大型社群為庫的改進做出了貢獻,並開發了各種應用。
- 易於測試 - Redux 的程式碼主要是小巧、純粹和獨立的功能。這使程式碼可測試且獨立。
- 組織 - Redux 準確地說明了程式碼的組織方式,這使得程式碼在團隊使用時更加一致和簡單。
React 路由
46. 什麼是React 路由?
React 路由是一個構建在 React 之上的強大的路由庫,它有助於嚮應用程式新增新的螢幕和流。這使 URL 與網頁上顯示的資料保持同步。它負責維護標準化的結構和行為,並用於開發單頁 Web 應用。 React 路由有一個簡單的API。
47. 為什麼React Router v4中使用 switch 關鍵字 ?
雖然 <div>
** 用於封裝 Router 中的多個路由,當你想要僅顯示要在多個定義的路線中呈現的單個路線時,可以使用 “switch” 關鍵字。使用時,<switch>
** 標記會按順序將已定義的 URL 與已定義的路由進行匹配。找到第一個匹配項後,它將渲染指定的路徑。從而繞過其它路線。
48. 為什麼需要 React 中的路由?
Router 用於定義多個路由,當使用者定義特定的 URL 時,如果此 URL 與 Router 內定義的任何 “路由” 的路徑匹配,則使用者將重定向到該特定路由。所以基本上我們需要在自己的應用中新增一個 Router 庫,允許建立多個路由,每個路由都會向我們提供一個獨特的檢視
<switch>
<route exact path=’/’ component={Home}/>
<route path=’/posts/:id’ component={Newpost}/>
<route path=’/posts’ component={Post}/>
</switch>
複製程式碼
49. 列出 React Router 的優點。
幾個優點是:
- 就像 React 基於元件一樣,在 React Router v4 中,API 是 'All About Components'。可以將 Router 視覺化為單個根元件(
<BrowserRouter>
),其中我們將特定的子路由(<route>
)包起來。 - 無需手動設定歷史值:在 React Router v4 中,我們要做的就是將路由包裝在
<BrowserRouter>
元件中。 - 包是分開的:共有三個包,分別用於 Web、Native 和 Core。這使我們應用更加緊湊。基於類似的編碼風格很容易進行切換。
50. React Router與常規路由有何不同?
主題 | 常規路由 | React 路由 |
---|---|---|
參與的頁面 | 每個檢視對應一個新檔案 | 只涉及單個HTML頁面 |
URL 更改 | HTTP 請求被髮送到伺服器並且接收相應的 HTML 頁面 | 僅更改歷史記錄屬性 |
體驗 | 使用者實際在每個檢視的不同頁面切換 | 使用者認為自己正在不同的頁面間切換 |
希望這套 React 面試題和答案能幫你準備面試。祝一切順利!