若是你是一位有理想的前端開發人員,而且正在準備面試,那麼這篇文章就是爲你準備的。本文收集了 React 面試中最多見的 50 大問題,這是一份理想的指南,讓你爲 React 相關的面試作好充分的準備工做。首先咱們快速瞭解一下 React 在市場上的需求和現狀,而後再開始討論 React 面試問題。前端
JavaScript 工具的市場地位正在緩慢而穩定地上升當中,而對 React 認證的需求正在飛速增加。選擇正確的技術來開發應用程序或網站變得越發艱難。React 被認爲是 Javascript 語言中增加最快的框架。react
虛擬 DOM 和可複用部件等獨特特性吸引了前端開發人員的注意。儘管成熟的框架(如 Angular、Meteor 和 Vue 等)在 MVC(模型 - 視圖 - 控制器)中只是一個「視圖」庫,但它們都有很強的競爭力。下圖顯示了常見 JS 框架的趨勢:git
如下是面試官最有可能提出的 50 個面試問題和答案。程序員
真實 DOM 和虛擬 DOM 的區別github
真實 DOM | 虛擬 DOM |
---|---|
1.更新較慢 | 1.更新較快 |
2.能夠直接更新 HTML | 2.不能直接更新 HTML |
3.元素更新時建立一個新 DOM | 3.元素更新時更新 JSX |
4.DOM 操做開銷較大 | 4.DOM 操做很是容易 |
5.內存浪費嚴重 | 5.沒有內存浪費 |
什麼是 React?web
React 的特色是什麼?面試
列出 React 的一些主要優點。數組
React 有哪些侷限?瀏覽器
什麼是 JSX?服務器
JSX 是 JavaScript XML 的簡寫。這是 React 使用的一種文件類型,具有 JavaScript 的表現力,並使用 HTML 做爲模板語法。這樣一來 HTML 文件理解起來就很是簡單。這種文件能夠創造穩健的應用程序並提升其效率。下面是一個 JSX 實例:
render(){ return( <div> <h1> Hello World from Codersera!!</h1> </div> ); }
虛擬 DOM 是輕量級的 JavaScript 對象,一開始只是真實 DOM 的一個副本。它是一個節點樹,將組件列爲對象及其屬性和內容的列表。React 的渲染功能從 React 的各個部分生成一個節點樹。而後,它會根據由不一樣用戶或系統行爲引發的信息模型突變來更新此樹。 虛擬 DOM 的工做機制只有簡單的三步組成。
1. 每當任何基礎信息更改時,整個 UI 就會以虛擬 DOM 的表示形式從新渲染。
2. 而後計算先前的 DOM 表示和新的 DOM 表示之間的區別。
3. 計算完成後,只有實際更改的內容纔會更新到真實 DOM。
React 使用 JSX(JavaScript eXtension),咱們能夠用它編寫相似於 HTML 的 JavaScript。但因爲 JSX 不是合法的 JavaScript,所以瀏覽器沒法直接讀取它。若是 JavaScript 文件包含 JSX,則必須將其轉換。你須要一個轉換器將 JSX 轉換爲瀏覽器能夠理解的常規 Javascript。目前最經常使用的轉換器是 Babel。
ES5 和 ES6 的語法區別以下:
// ES5 var React = require('react'); // ES6 import React from 'react'; ******** export vs exports ********* // ES5 module.exports = Component; // ES6 export default Component; ****** function ***** // ES5 var MyComponent = React.createClass({ render: function() { return <h3> Hello CoderSera! </h3> }, }); // ES6 class MyComponent extends React.Component { render() { return <h3> Hello CoderSera! </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> } render() { return; <h3> Hello, { this.state.name }! < /h3> }
React 對比 Angular | React | Angular |
---|---|---|
架構 | 使用虛擬 DOM | 使用真實 DOM |
渲染 | 服務端渲染 | 客戶端渲染 |
DOM | 使用虛擬 DOM | 使用真實 DOM |
數據綁定 | 單向數據綁定 | 雙向數據綁定 |
調試 | 編譯時調試 | 運行時調試 |
開發者 | 谷歌 |
React 應用程序的 UI 構建塊都是組件。這些部分將整個 UI 劃分爲許多可自治和可複用的微小部分。而後獨立的某個部分發生變化就不會影響 UI 的其他部分。
它被視爲普通函數,但 render() 函數必須返回某些值,不管值是否爲空。調用組件文件時默認會調用 render() 方法,由於組件須要顯示 HTML 標記,或者咱們能夠說 JSX 語法。每一個 React 組件必須有一個 render() 函數,它返回單個 React 元素,該元素表明原生 DOM 組件。若是須要渲染多個 HTML 元素,則必須將它們分組在一個封閉的標籤內,如form、group和div等。此函數必須保持純淨,就是說它在每次調用時必須返回相同的結果。
import React, { Component } from 'react'; class App extends Component { render() { return (<div> <h1 className='App-title'> hello CoderSera </h1></div>) } } export default App;
Hooks 是一項新功能,使你無需編寫類便可使用狀態等 React 功能。來看一個 useState hook 示例。
<em>import </em>{useState} <em>from </em>'react';<br><br><em>function </em>Example() {<br> <em>// Declare a new
Props 用於將數據從父級傳遞到子級或由組件自己傳遞。它們是不可變的,所以不會更改。
Props 是不可變的。由於它們是基於純函數的概念開發的。在純函數中,咱們沒法更改參數數據。所以在 ReactJS 中也沒法更改 props 的數據。
組件能夠經過狀態來跟蹤其執行的任何渲染之間的信息。
狀態用於可變數據或將要更改的數據。這對於用戶輸入尤爲方便。以搜索欄爲例,用戶輸入數據時他們看到的內容也會更新。
條件 | 狀態 | Props |
---|---|---|
從父組件接收初始值 | 是 | 是 |
父組件能夠更改值 | 否 | 是 |
在組件內設置默認值 | 是 | 是 |
在組件內更改 | 是 | 否 |
爲子組件設置初始值 | 是 | 是 |
在子組件內更改 | 否 | 是 |
可使用 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 中的箭頭函數是什麼?如何使用?
粗箭頭=> 用於定義匿名函數,這一般是將參數傳遞給回調函數的最簡單方法。可是你須要在使用它時優化性能。注意:每次渲染組件時,在 render 方法中使用箭頭函數都會建立一個新函數,這可能會影響性能。
//General way render() { return( <MyInput onChange={this.handleChange.bind(this) } /> ); } //With Arrow Function render() { return( <MyInput onChange={ (e) => this.handleOnChange(e) } /> ); }
有狀態組件 | 無狀態組件 |
---|---|
在內存中存儲組件狀態更改的信息 | 計算組件的內部狀態 |
有權更改狀態 | 無權更改狀態 |
包含過去、如今和可能的將來狀態更改的信息 | 沒有包含關於狀態更改的信息 |
無狀態組件通知它們關於狀態更改的需求,而後它們將 props 傳遞給前者 | 它們從有狀態組件接收 props,將其視爲回調函數 |
React 組件的生命週期分爲三個不一樣階段:
初始化:在初始化階段,咱們爲 this.props 和 this.state 定義默認值和初始值。
掛載:掛載是將組件插入 DOM 時發生的過程
更新:這個階段中,每當狀態更改或組件收到新的 prop 時,組件都會更新
卸載:這是從 DOM 卸載組件的階段。
一些最重要的生命週期方法包括:
componentWillMount()——在初始渲染髮生以前,即在 React 將組件插入 DOM 以前當即調用一次。請務必注意,在此方法中調用 this.setState() 不會觸發從新渲染。
componentDidMount()——在渲染函數以後觸發此方法。如今能夠訪問更新的 DOM,這意味着該方法是初始化其餘須要訪問 DOM 的 Javascript 庫以及數據提取操做的最佳選擇。
componentWillReceiveProps()——componentWillReceiveProps() 在組件接收新 props 時調用。在調用 render() 方法以前,咱們能夠用這個方法對 prop 過渡作出反應。在此函數中調用 this.setState() 不會觸發額外的從新渲染,咱們能夠經過 this.props 訪問舊的 props。
shouldComponentUpdate()——咱們能夠用它來決定下一個組件的狀態是否應觸發從新渲染。此方法返回一個布爾值,默認爲 true。可是咱們能夠返回 false,而且不會調用如下方法:
componentWillUpdate()——當接收到新的 props 或狀態時,在渲染(更新)以前當即調用此方法。咱們能夠用它在更新以前作準備,可是不容許使用 this.setState()。
componentDidUpdate()——React 更新 DOM 後當即調用此方法。咱們可使用此方法與更新後的 DOM 交互,或執行任何渲染後操做。
componentWillUnmount()——從 DOM 卸載組件以前當即調用此方法。咱們能夠用它執行可能須要的任何清理工做。
在 React 中,事件是對特定動做(如鼠標懸停、鼠標單擊和按鍵等)觸發的反應。處理這些事件相似於處理 DOM 元素上的事件。可是在語法上存在一些差別,例如:
事件命名使用駝峯式大小寫,而不是僅使用小寫字母。
事件做爲函數而不是字符串傳遞。
事件參數包含一組特定於事件的屬性。每一個事件類型都包含它本身的屬性和行爲,這些屬性和行爲只能經過它的事件處理程序訪問。
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> ); } });
合成事件是圍繞瀏覽器原生事件充當跨瀏覽器包裝器的對象。它們將不一樣的瀏覽器行爲合併爲一個 API。這樣作是爲了確保在各個瀏覽器的事件中顯示一致的特徵。
Ref 是 React 引用的簡寫。它是一個屬性,幫助存儲對特定元素或組件的引用,由組件渲染的配置函數返回。它用於返回對渲染返回的特定元素或組件的引用。當咱們須要 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> ); } }
如下是應使用 ref 的狀況:
當你須要管理焦點、選擇文本或媒體播放時。
觸發命令式動畫。
與第三方 DOM 庫集成。
可使用 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> ); } }
React 提供了一種有狀態的,響應式的方法來構建表單。與其餘 DOM 元素不一樣,HTML 表單元素在 React 中的工做機制有所不一樣。例如,表單數據一般由組件而不是 DOM 處理,而且一般使用受控組件來實現。 區別在於可使用回調函數來處理表單事件,而後使用容器的狀態存儲表單數據。這使你的組件能夠更好地控制表單控制元素和表單數據。 回調函數是在發生事件(包括更改表單控制值或表單提交)時觸發的。
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> ); }
受控組件 | 非受控組件 |
---|---|
它們不維護本身的狀態 | 它們維護本身的狀態 |
數據由父組件控制 | 數據由 DOM 控制 |
它們經過 props 得到當前值,而後經過回調通知更改 | 使用引用來得到它們的當前值 |
React 中的高階組件是一種在組件之間共享通用功能而無需重複代碼的模式。 高階組件實際上不是組件,它是一個接受組件並返回新組件的函數。它將一個組件轉換爲另外一個組件,並添加其餘數據或功能
HOC 可用於許多任務,例如:
代碼複用,邏輯和引導抽象。
渲染劫持。
狀態抽象和控制。
Props 操控。
React 並無在咱們的組件中編寫 shouldComponent 方法,而是引入了一個帶有內置 shouldComponentUpdate 實現的新組件,它是 React.PureComponent 組件。 React.PureComponent 經過淺層 prop 和狀態比較來實現它。在某些狀況下,你可使用 React.PureComponent 來提升性能。
鍵可幫助 React 識別哪些項目已更改、添加或刪除。應該爲數組內的元素提供鍵,以賦予元素穩定的身份。鍵必須是惟一的。 當使用動態建立的組件或用戶更改列表時,React 鍵很是有用。設置鍵值後,更改後的組件就能保持惟一標識。
如下是 MVC 框架的一些主要問題:
Flux 是 Facebook 內部與 React 搭配使用的架構。它不是框架或庫。只是一種新型的體系結構,是對 React 和單向數據流概念的補充:
Flux 的各個組成部分以下:
Redux 是一種狀態管理工具。儘管它主要與 React 搭配使用,但也能夠與其餘任何 JavaScript 框架或庫搭配。
Redux 容許你在一個稱爲存儲(Store)的對象中管理整個應用程序狀態。
對存儲的更新將觸發與存儲的已更新部分鏈接的組件的從新渲染。當咱們想要更新某些東西時,咱們稱之爲動做(Action)。咱們還建立函數來處理這些動做並返回更新的存儲。這些函數稱爲 Reducer。
單一可信來源:整個應用程序的狀態存儲在單個存儲區中的對象 / 狀態樹中。單一狀態樹使咱們能更容易地跟蹤歷史更改,更方便地調試或檢查應用程序。
狀態是隻讀的:更改狀態的惟一方法是觸發動做。動做是描述更改的普通 JS 對象。就像狀態是數據的最小表示同樣,動做是數據更改的最小表示。
使用純函數更改:爲了確認動做是如何轉換狀態樹的,你須要純函數。純函數是返回值僅取決於其參數值的函數。
單一可信源(SSOT)是構造信息模型和相關數據模式的實踐,其中每一個數據元素都只能在一個地方掌握(或編輯) Redux 使用「存儲」將應用程序的整個狀態存儲在一個位置。所以,組件的全部狀態都存儲在存儲中,而且存儲自己會接收更新。單一狀態樹使咱們能更容易地跟蹤歷史更改,更方便地調試或檢查應用程序。
Redux 由如下組件組成:
React 中的動做必須具備 type 屬性,該屬性指示正在執行的 ACTION 的類型。必須將它們定義爲字符串常量,你也能夠爲其添加更多屬性。在 Redux 中使用稱爲「動做建立者」的函數來建立動做。如下是動做和動做建立者的示例:
function addTodo(text) { return { type: ADD_TODO, text } }
Reducer 是用於指示 ACTION 反應中應用程序狀態變化的簡單功能。它接收先前的狀態和動做,而後返回新的狀態。它根據動做類型肯定須要哪一種更新,而後返回新值。若是沒有要完成的工做,它將按原樣返回先前狀態。
存儲是一個 JavaScript 對象,能夠保存應用程序的狀態,並提供一些輔助方法來訪問狀態、調度動做並記錄偵聽器。應用程序的整個狀態 / 對象樹存儲在單個存儲中。所以 Redux 很是容易理解且可預測。咱們能夠將中間件轉移到存儲,以管理數據處理任務,並維護更改存儲狀態的各類活動的日誌。經過 Reducer,全部活動都返回新的狀態。
Flux | Redux |
---|---|
存儲包括狀態和更改邏輯 | 存儲和更改邏輯是分離的 |
有多個存儲 | 只有一個存儲 |
全部存儲不互通,是平行的 | 帶有分層 Reducer 的單個存儲 |
有單個調度器 | 沒有調度器的概念 |
React 組件訂閱到存儲 | 容器組件是有聯繫的 |
狀態是可變的 | 狀態是不可變的 |
Redux 的優勢以下:
React Router 是創建在 React 之上的功能強大的路由庫。它使 URL 與網頁上顯示的數據保持同步。它保持標準化的結構和行爲,可用於開發單頁 Web 應用程序。React Router 有一個簡單的 API。React Router 提供了一種方法,只會顯示你的應用中路由匹配你的定義的那些組件。
在 Switch 組件內,Route和Redirect組件嵌套在內部。從 Switch 頂部的 Route/Redirect 組件開始到底部的 Route/Redirect,根據瀏覽器中當前的 URL 是否與 Route/Redirect 組件的 prop/ 路徑匹配,將每一個組件評估爲 true 或 false。 Switch 只會渲染第一個匹配的子級。當咱們嵌套了下面這樣的路由時真的很方便:
<Switch>
<Route path="/accounts/new" component={AddForm} /> <Route path={`/accounts/:accountId`} component={Profile} /> </Switch>
路由器用於定義多個路由,而且當用戶鍵入特定的 URL 時,若是該 URL 與路由器內部定義的任何「路由」的路徑匹配,則該用戶將被重定向到該路由。所以咱們須要在應用程序中添加一個路由器庫,以容許建立多個路由,每一個路由都爲咱們指向一個獨特的視圖。
從 React Router 包導入的組件有兩個屬性,一個是將用戶引導到指定路徑的 path,另外一個是用於定義所述路徑中內容的 component。
<switch>
<route exact path=’/’ component={Home}/> <route path=’/posts/:id’ component={Newpost}/> <route path=’/posts’ component={Post}/> </switch>
幾個優勢是:
就像 React 基於組件的理念同樣,在 React Router v4 中 API 是「徹底組件化的」。路由器能夠可視化爲單個根組件(),其中包含特定的子路由()。
無需手動設置歷史值:在 React Router v4 中,咱們要作的就是將路由包裝在組件中。
包是拆分的:三個包分別用於 Web、Native 和 Core。這使咱們的應用更加緊湊。它們的編碼樣式相似,因此很容易來回切換。
React Router 與傳統路由有何不一樣?
~ | 傳統路由 | React 路由 |
---|---|---|
參與的頁面 | 每一個視圖對應一個新頁面 | 只涉及單個 HTML 頁面 |
URL 更改 | 向服務器發送一個 HTTP 請求並接收對應的 HTML 頁面 | 只有歷史屬性被更改 |
體驗 | 用戶實際上是在每一個視圖的不一樣頁面間切換 | 用戶覺得本身正在不一樣的頁面間切換 |
原文連接:https://codersera.com/blog/top-50-react-questions-you-need-to-prepare-for-the-interview-in-2019/