如果你是一位有抱負(fù)的前端程序員并準(zhǔn)備面試,那么這篇文章很適合你。本文是你學(xué)習(xí)和面試 React 所需知識(shí)的完美指南。
JavaScript 工具緩慢而穩(wěn)定地在市場(chǎng)中扎根,對(duì) React 的需求呈指數(shù)級(jí)增長(zhǎng)。選擇合適的技術(shù)來(lái)開(kāi)發(fā)應(yīng)用或網(wǎng)站變得越來(lái)越有挑戰(zhàn)性。其中 React 被認(rèn)為是增長(zhǎng)最快的 Javascript 框架。
截至今天,Github 上約有1,000名貢獻(xiàn)者。 Virtual DOM 和可重用組件等獨(dú)特功能吸引了前端開(kāi)發(fā)人員的注意力。盡管它只是 MVC(模型 – 視圖 – 控制器)中“視圖”的庫(kù),但它對(duì) Angular,Meteor,Vue 等全面的框架也構(gòu)成了強(qiáng)力的挑戰(zhàn)。下圖為流行的 JS 框架的趨勢(shì):
JS 框架的趨勢(shì)
React 面試題
以下是面試官最有可能問(wèn)到的 50 個(gè) React 面試題和答案。為方便你學(xué)習(xí),我對(duì)它們進(jìn)行了分類:
- 基本知識(shí)
- React 組件
- React Redux
- React 路由
基本知識(shí)
1. 區(qū)分Real DOM和Virtual DOM
Real DOM | Virtual DOM |
---|---|
1. 更新緩慢。 | 1. 更新更快。 |
2. 可以直接更新 HTML。 | 2. 無(wú)法直接更新 HTML。 |
3. 如果元素更新,則創(chuàng)建新DOM。 | 3. 如果元素更新,則更新 JSX 。 |
4. DOM操作代價(jià)很高。 | 4. DOM 操作非常簡(jiǎn)單。 |
5. 消耗的內(nèi)存較多。 | 5. 很少的內(nèi)存消耗。 |
2. 什么是React?
- React 是 Facebook 在 2011 年開(kāi)發(fā)的前端 JavaScript 庫(kù)。
- 它遵循基于組件的方法,有助于構(gòu)建可重用的UI組件。
- 它用于開(kāi)發(fā)復(fù)雜和交互式的 Web 和移動(dòng) UI。
- 盡管它僅在 2015 年開(kāi)源,但有一個(gè)很大的支持社區(qū)。
3. React有什么特點(diǎn)?
React的主要功能如下:
- 它使用虛擬DOM 而不是真正的DOM。
- 它可以進(jìn)行服務(wù)器端渲染。
- 它遵循單向數(shù)據(jù)流或數(shù)據(jù)綁定。
4. 列出React的一些主要優(yōu)點(diǎn)。
React的一些主要優(yōu)點(diǎn)是:
- 它提高了應(yīng)用的性能
- 可以方便地在客戶端和服務(wù)器端使用
- 由于 JSX,代碼的可讀性很好
- React 很容易與 Meteor,Angular 等其他框架集成
- 使用React,編寫(xiě)UI測(cè)試用例變得非常容易
5. React有哪些限制?
React的限制如下:
- React 只是一個(gè)庫(kù),而不是一個(gè)完整的框架
- 它的庫(kù)非常龐大,需要時(shí)間來(lái)理解
- 新手程序員可能很難理解
- 編碼變得復(fù)雜,因?yàn)樗褂脙?nèi)聯(lián)模板和 JSX
6. 什么是JSX?
JSX 是J avaScript XML 的簡(jiǎn)寫(xiě)。是 React 使用的一種文件,它利用 JavaScript 的表現(xiàn)力和類似 HTML 的模板語(yǔ)法。這使得 HTML 文件非常容易理解。此文件能使應(yīng)用非??煽浚⒛軌蛱岣咂湫阅?。下面是JSX的一個(gè)例子:
render(){ return( <p> <h1> Hello World from Edureka!!</h1> </p> ); }
7. 你了解 Virtual DOM 嗎?解釋一下它的工作原理。
Virtual DOM 是一個(gè)輕量級(jí)的 JavaScript 對(duì)象,它最初只是 real DOM 的副本。它是一個(gè)節(jié)點(diǎn)樹(shù),它將元素、它們的屬性和內(nèi)容作為對(duì)象及其屬性。 React 的渲染函數(shù)從 React 組件中創(chuàng)建一個(gè)節(jié)點(diǎn)樹(shù)。然后它響應(yīng)數(shù)據(jù)模型中的變化來(lái)更新該樹(shù),該變化是由用戶或系統(tǒng)完成的各種動(dòng)作引起的。
Virtual DOM 工作過(guò)程有三個(gè)簡(jiǎn)單的步驟。
1.每當(dāng)?shù)讓訑?shù)據(jù)發(fā)生改變時(shí),整個(gè) UI 都將在 Virtual DOM 描述中重新渲染。
2.然后計(jì)算之前 DOM 表示與新表示的之間的差異。
3.完成計(jì)算后,將只用實(shí)際更改的內(nèi)容更新 real DOM。
8. 為什么瀏覽器無(wú)法讀取JSX?
瀏覽器只能處理 JavaScript 對(duì)象,而不能讀取常規(guī) JavaScript 對(duì)象中的 JSX。所以為了使瀏覽器能夠讀取 JSX,首先,需要用像 Babel 這樣的 JSX 轉(zhuǎn)換器將 JSX 文件轉(zhuǎn)換為 JavaScript 對(duì)象,然后再將其傳給瀏覽器。
9. 與 ES5 相比,React 的 ES6 語(yǔ)法有何不同?
以下語(yǔ)法是 ES5 與 ES6 中的區(qū)別:
1.require 與 import
// ES5 var React = require('react'); // ES6 import React from 'react';
2.export 與 exports
// ES5 module.exports = Component; // ES6 export default Component;
3.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>; } }
4.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>; } }
5.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. 體系結(jié)構(gòu) | 只有 MVC 中的 View | 完整的 MVC |
2. 渲染 | 可以進(jìn)行服務(wù)器端渲染 | 客戶端渲染 |
3. DOM | 使用 virtual DOM | 使用 real DOM |
4. 數(shù)據(jù)綁定 | 單向數(shù)據(jù)綁定 | 雙向數(shù)據(jù)綁定 |
5. 調(diào)試 | 編譯時(shí)調(diào)試 | 運(yùn)行時(shí)調(diào)試 |
6. 作者 |
React 組件
11. 你怎樣理解“在React中,一切都是組件”這句話。
組件是 React 應(yīng)用 UI 的構(gòu)建塊。這些組件將整個(gè) UI 分成小的獨(dú)立并可重用的部分。每個(gè)組件彼此獨(dú)立,而不會(huì)影響 UI 的其余部分。
12. 怎樣解釋 React 中 render() 的目的。
每個(gè)React組件強(qiáng)制要求必須有一個(gè) render()。它返回一個(gè) React 元素,是原生 DOM 組件的表示。如果需要渲染多個(gè) HTML 元素,則必須將它們組合在一個(gè)封閉標(biāo)記內(nèi),例如 <form>
、<group>
、<p>
等。此函數(shù)必須保持純凈,即必須每次調(diào)用時(shí)都返回相同的結(jié)果。
13. 如何將兩個(gè)或多個(gè)組件嵌入到一個(gè)組件中?
可以通過(guò)以下方式將組件嵌入到一個(gè)組件中:
class MyComponent extends React.Component{ render(){ return( <p> <h1>Hello</h1> <Header/> </p> ); } } class Header extends React.Component{ render(){ return <h1>Header Component</h1> }; } ReactDOM.render( <MyComponent/>, document.getElementById('content') );
14. 什么是 Props?
Props 是 React 中屬性的簡(jiǎn)寫(xiě)。它們是只讀組件,必須保持純,即不可變。它們總是在整個(gè)應(yīng)用中從父組件傳遞到子組件。子組件永遠(yuǎn)不能將 prop 送回父組件。這有助于維護(hù)單向數(shù)據(jù)流,通常用于呈現(xiàn)動(dòng)態(tài)生成的數(shù)據(jù)。
15. React中的狀態(tài)是什么?它是如何使用的?
狀態(tài)是 React 組件的核心,是數(shù)據(jù)的來(lái)源,必須盡可能簡(jiǎn)單?;旧蠣顟B(tài)是確定組件呈現(xiàn)和行為的對(duì)象。與props 不同,它們是可變的,并創(chuàng)建動(dòng)態(tài)和交互式組件??梢酝ㄟ^(guò) this.state()
訪問(wèn)它們。
16. 區(qū)分狀態(tài)和 props
條件 | State | Props |
---|---|---|
1. 從父組件中接收初始值 | Yes | Yes |
2. 父組件可以改變值 | No | Yes |
3. 在組件中設(shè)置默認(rèn)值 | Yes | Yes |
4. 在組件的內(nèi)部變化 | Yes | No |
5. 設(shè)置子組件的初始值 | Yes | Yes |
6. 在子組件的內(nèi)部更改 | No | Yes |
17. 如何更新組件的狀態(tài)?
可以用 this.setState()
更新組件的狀態(tài)。
class MyComponent extends React.Component { constructor() { super(); this.state = { name: 'Maxx', id: '101' } } render() { setTimeout(()=>{this.setState({name:'Jaeha', id:'222'})},2000) return ( <p> <h1>Hello {this.state.name}</h1> <h2>Your Id is {this.state.id}</h2> </p> ); } } ReactDOM.render( <MyComponent/>, document.getElementById('content') );
18. React 中的箭頭函數(shù)是什么?怎么用?
箭頭函數(shù)(=>)是用于編寫(xiě)函數(shù)表達(dá)式的簡(jiǎn)短語(yǔ)法。這些函數(shù)允許正確綁定組件的上下文,因?yàn)樵?ES6 中默認(rèn)下不能使用自動(dòng)綁定。使用高階函數(shù)時(shí),箭頭函數(shù)非常有用。
//General way render() { return( <MyInput onChange = {this.handleChange.bind(this) } /> ); } //With Arrow Function render() { return( <MyInput onChange = { (e)=>this.handleOnChange(e) } /> ); }
19. 區(qū)分有狀態(tài)和無(wú)狀態(tài)組件。
有狀態(tài)組件 | 無(wú)狀態(tài)組件 |
---|---|
1. 在內(nèi)存中存儲(chǔ)有關(guān)組件狀態(tài)變化的信息 | 1. 計(jì)算組件的內(nèi)部的狀態(tài) |
2. 有權(quán)改變狀態(tài) | 2. 無(wú)權(quán)改變狀態(tài) |
3. 包含過(guò)去、現(xiàn)在和未來(lái)可能的狀態(tài)變化情況 | 3. 不包含過(guò)去,現(xiàn)在和未來(lái)可能發(fā)生的狀態(tài)變化情況 |
4. 接受無(wú)狀態(tài)組件狀態(tài)變化要求的通知,然后將 props 發(fā)送給他們。 | 4.從有狀態(tài)組件接收 props 并將其視為回調(diào)函數(shù)。 |
20. React組件生命周期的階段是什么?
React 組件的生命周期有三個(gè)不同的階段:
- 初始渲染階段:這是組件即將開(kāi)始其生命之旅并進(jìn)入 DOM 的階段。
- 更新階段:一旦組件被添加到 DOM,它只有在 prop 或狀態(tài)發(fā)生變化時(shí)才可能更新和重新渲染。這些只發(fā)生在這個(gè)階段。
- 卸載階段:這是組件生命周期的最后階段,組件被銷毀并從 DOM 中刪除。
21. 詳細(xì)解釋 React 組件的生命周期方法。
一些最重要的生命周期方法是:
- componentWillMount() – 在渲染之前執(zhí)行,在客戶端和服務(wù)器端都會(huì)執(zhí)行。
- componentDidMount() – 僅在第一次渲染后在客戶端執(zhí)行。
- componentWillReceiveProps() – 當(dāng)從父類接收到 props 并且在調(diào)用另一個(gè)渲染器之前調(diào)用。
- shouldComponentUpdate() – 根據(jù)特定條件返回 true 或 false。如果你希望更新組件,請(qǐng)返回true 否則返回 false。默認(rèn)情況下,它返回 false。
- componentWillUpdate() – 在 DOM 中進(jìn)行渲染之前調(diào)用。
- componentDidUpdate() – 在渲染發(fā)生后立即調(diào)用。
- componentWillUnmount() – 從 DOM 卸載組件后調(diào)用。用于清理內(nèi)存空間。
22. React中的事件是什么?
在 React 中,事件是對(duì)鼠標(biāo)懸停、鼠標(biāo)單擊、按鍵等特定操作的觸發(fā)反應(yīng)。處理這些事件類似于處理 DOM 元素中的事件。但是有一些語(yǔ)法差異,如:
- 用駝峰命名法對(duì)事件命名而不是僅使用小寫(xiě)字母。
- 事件作為函數(shù)而不是字符串傳遞。
事件參數(shù)重包含一組特定于事件的屬性。每個(gè)事件類型都包含自己的屬性和行為,只能通過(guò)其事件處理程序訪問(wèn)。
23. 如何在React中創(chuàng)建一個(gè)事件?
class Display extends React.Component({ show(evt) { // code }, render() { // Render the p with an onClick prop (value is a function) return ( <p onClick={this.show}>Click Me!</p> ); } });
24. React中的合成事件是什么?
合成事件是圍繞瀏覽器原生事件充當(dāng)跨瀏覽器包裝器的對(duì)象。它們將不同瀏覽器的行為合并為一個(gè) API。這樣做是為了確保事件在不同瀏覽器中顯示一致的屬性。
25. 你對(duì) React 的 refs 有什么了解?
Refs 是 React 中引用的簡(jiǎn)寫(xiě)。它是一個(gè)有助于存儲(chǔ)對(duì)特定的 React 元素或組件的引用的屬性,它將由組件渲染配置函數(shù)返回。用于對(duì) render() 返回的特定元素或組件的引用。當(dāng)需要進(jìn)行 DOM 測(cè)量或向組件添加方法時(shí),它們會(huì)派上用場(chǎng)。
class ReferenceDemo extends React.Component{ display() { const name = this.inputDemo.value; document.getElementById('disp').innerHTML = name; } render() { return( <p> Name: <input type="text" ref={input => this.inputDemo = input} /> <button name="Click" onClick={this.display}>Click</button> <h2>Hello <span id="disp"></span> !!!</h2> </p> ); } }
26. 列出一些應(yīng)該使用 Refs 的情況。
以下是應(yīng)該使用 refs 的情況:
- 需要管理焦點(diǎn)、選擇文本或媒體播放時(shí)
- 觸發(fā)式動(dòng)畫(huà)
- 與第三方 DOM 庫(kù)集成
27. 如何模塊化 React 中的代碼?
可以使用 export 和 import 屬性來(lái)模塊化代碼。它們有助于在不同的文件中單獨(dú)編寫(xiě)組件。
//ChildComponent.jsx export default class ChildComponent extends React.Component { render() { return( <p> <h1>This is a child component</h1> </p> ); } } //ParentComponent.jsx import ChildComponent from './childcomponent.js'; class ParentComponent extends React.Component { render() { return( <p> <App /> </p> ); } }
28. 如何在 React 中創(chuàng)建表單
React 表單類似于 HTML 表單。但是在 React 中,狀態(tài)包含在組件的 state 屬性中,并且只能通過(guò) setState()
更新。因此元素不能直接更新它們的狀態(tài),它們的提交是由 JavaScript 函數(shù)處理的。此函數(shù)可以完全訪問(wèn)用戶輸入到表單的數(shù)據(jù)。
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. 你對(duì)受控組件和非受控組件了解多少?
受控組件 | 非受控組件 |
---|---|
1. 沒(méi)有維持自己的狀態(tài) | 1. 保持著自己的狀態(tài) |
2.數(shù)據(jù)由父組件控制 | 2.數(shù)據(jù)由 DOM 控制 |
3. 通過(guò) props 獲取當(dāng)前值,然后通過(guò)回調(diào)通知更改 | 3. Refs 用于獲取其當(dāng)前值 |
30. 什么是高階組件(HOC)?
高階組件是重用組件邏輯的高級(jí)方法,是一種源于 React 的組件模式。 HOC 是自定義組件,在它之內(nèi)包含另一個(gè)組件。它們可以接受子組件提供的任何動(dòng)態(tài),但不會(huì)修改或復(fù)制其輸入組件中的任何行為。你可以認(rèn)為 HOC 是“純(Pure)”組件。
31. 你能用HOC做什么?
HOC可用于許多任務(wù),例如:
- 代碼重用,邏輯和引導(dǎo)抽象
- 渲染劫持
- 狀態(tài)抽象和控制
- Props 控制
32. 什么是純組件?
純(Pure) 組件是可以編寫(xiě)的最簡(jiǎn)單、最快的組件。它們可以替換任何只有 render() 的組件。這些組件增強(qiáng)了代碼的簡(jiǎn)單性和應(yīng)用的性能。
33. React 中 key 的重要性是什么?
key 用于識(shí)別唯一的 Virtual DOM 元素及其驅(qū)動(dòng) UI 的相應(yīng)數(shù)據(jù)。它們通過(guò)回收 DOM 中當(dāng)前所有的元素來(lái)幫助 React 優(yōu)化渲染。這些 key 必須是唯一的數(shù)字或字符串,React 只是重新排序元素而不是重新渲染它們。這可以提高應(yīng)用程序的性能。
React Redux
34. MVC框架的主要問(wèn)題是什么?
以下是MVC框架的一些主要問(wèn)題:
- 對(duì) DOM 操作的代價(jià)非常高
- 程序運(yùn)行緩慢且效率低下
- 內(nèi)存浪費(fèi)嚴(yán)重
- 由于循環(huán)依賴性,組件模型需要圍繞 models 和 views 進(jìn)行創(chuàng)建
35. 解釋一下 Flux
Flux 是一種強(qiáng)制單向數(shù)據(jù)流的架構(gòu)模式。它控制派生數(shù)據(jù),并使用具有所有數(shù)據(jù)權(quán)限的中心 store 實(shí)現(xiàn)多個(gè)組件之間的通信。整個(gè)應(yīng)用中的數(shù)據(jù)更新必須只能在此處進(jìn)行。 Flux 為應(yīng)用提供穩(wěn)定性并減少運(yùn)行時(shí)的錯(cuò)誤。
36. 什么是Redux?
Redux 是當(dāng)今最熱門(mén)的前端開(kāi)發(fā)庫(kù)之一。它是 JavaScript 程序的可預(yù)測(cè)狀態(tài)容器,用于整個(gè)應(yīng)用的狀態(tài)管理。使用 Redux 開(kāi)發(fā)的應(yīng)用易于測(cè)試,可以在不同環(huán)境中運(yùn)行,并顯示一致的行為。
37. Redux遵循的三個(gè)原則是什么?
- 單一事實(shí)來(lái)源:整個(gè)應(yīng)用的狀態(tài)存儲(chǔ)在單個(gè) store 中的對(duì)象/狀態(tài)樹(shù)里。單一狀態(tài)樹(shù)可以更容易地跟蹤隨時(shí)間的變化,并調(diào)試或檢查應(yīng)用程序。
- 狀態(tài)是只讀的:改變狀態(tài)的唯一方法是去觸發(fā)一個(gè)動(dòng)作。動(dòng)作是描述變化的普通 JS 對(duì)象。就像 state 是數(shù)據(jù)的最小表示一樣,該操作是對(duì)數(shù)據(jù)更改的最小表示。
- 使用純函數(shù)進(jìn)行更改:為了指定狀態(tài)樹(shù)如何通過(guò)操作進(jìn)行轉(zhuǎn)換,你需要純函數(shù)。純函數(shù)是那些返回值僅取決于其參數(shù)值的函數(shù)。
38. 你對(duì)“單一事實(shí)來(lái)源”有什么理解?
Redux 使用 “Store” 將程序的整個(gè)狀態(tài)存儲(chǔ)在同一個(gè)地方。因此所有組件的狀態(tài)都存儲(chǔ)在 Store 中,并且它們從 Store 本身接收更新。單一狀態(tài)樹(shù)可以更容易地跟蹤隨時(shí)間的變化,并調(diào)試或檢查程序。
39. 列出 Redux 的組件。
Redux 由以下組件組成:
- Action – 這是一個(gè)用來(lái)描述發(fā)生了什么事情的對(duì)象。
- Reducer – 這是一個(gè)確定狀態(tài)將如何變化的地方。
- Store – 整個(gè)程序的狀態(tài)/對(duì)象樹(shù)保存在Store中。
- View – 只顯示 Store 提供的數(shù)據(jù)。
40. 數(shù)據(jù)如何通過(guò) Redux 流動(dòng)?
41. 如何在 Redux 中定義 Action?
React 中的 Action 必須具有 type 屬性,該屬性指示正在執(zhí)行的 ACTION 的類型。必須將它們定義為字符串常量,并且還可以向其添加