React高級面試題

Q1:什麼是虛擬DOM?

難度:⭐

虛擬DOM(VDOM)它是真實DOM的內存表示,一種編程概念,一種模式。它會和真實的DOM同步,好比經過ReactDOM這種庫,這個同步的過程叫作調和(reconcilation)。javascript

虛擬DOM更可能是一種模式,不是一種特定的技術。php

🔗 資料來源:github.com/sudheerj
🔗 參考資料:什麼是虛擬DOMcss

Q2:類組件和函數組件之間有什麼區別?

難度:⭐⭐
  • 類組件Class componentshtml

    • 不管是使用函數或是類來聲明一個組件,它決不能修改它本身的 propsjava

      • 全部 React 組件都必須是純函數,並禁止修改其自身 props
    • React是單項數據流,父組件改變了屬性,那麼子組件視圖會更新。react

      • 屬性 props是外界傳遞過來的,狀態 state是組件自己的,狀態能夠在組件中任意修改
      • 組件的屬性和狀態改變都會更新視圖。
class Welcome extends React.Component {
  render() {
    return (
      <h1>Welcome { this.props.name }</h1>
    );
  }
}
ReactDOM.render(<Welcome name='react' />, document.getElementById('root'));
  • 函數組件(functional component)git

    • 函數組件接收一個單一的 props 對象並返回了一個React元素
    function Welcome (props) {
      return <h1>Welcome {props.name}</h1>
    }
    ReactDOM.render(<Welcome name='react' />, document.getElementById('root'));

區別 github

函數組件和類組件固然是有區別的,並且函數組件的性能比類組件的性能要高,由於類組件使用的時候要實例化,而函數組件直接執行函數取返回結果便可。爲了提升性能,儘可能使用函數組件。算法

區別 函數組件 類組件
是否有 this 沒有
是否有生命週期 沒有
是否有狀態 state 沒有

🔗 資料來源:github.com/Pau1fitz編程

🔗 參考資料:函數組件與類組件區別

Q3:React中的refs做用是什麼?

難度:⭐⭐

Refs 是 React 提供給咱們的安全訪問 DOM 元素或者某個組件實例的句柄。
咱們能夠爲元素添加 ref 屬性而後在回調函數中接受該元素在 DOM 樹中的句柄,該值會做爲回調函數的第一個參數返回:

class UnControlledForm extends Component {
  handleSubmit = () => {
    console.log("Input Value: ", this.input.value)
  }
  render () {
    return (
      <form onSubmit={this.handleSubmit}>
        <input
          type='text'
          ref={(input) => this.input = input} />
        <button type='submit'>Submit</button>
      </form>
    )
  }
}

上述代碼中的 input 域包含了一個 ref 屬性,該屬性聲明的回調函數會接收 input 對應的 DOM 元素,咱們將其綁定到 this 指針以便在其餘的類函數中使用。
另外值得一提的是,refs 並非類組件的專屬,函數式組件一樣可以利用閉包暫存其值:

function CustomForm ({handleSubmit}) {
  let inputElement
  return (
    <form onSubmit={() => handleSubmit(inputElement.value)}>
      <input
        type='text'
        ref={(input) => inputElement = input} />
      <button type='submit'>Submit</button>
    </form>
  )
}

🔗 資料來源:github.com/Pau1fitz
🔗 參考資料:https://stackoverflow.com/que...

Q4:描述React事件處理。

難度:⭐⭐

爲了解決跨瀏覽器兼容性問題,React中的事件處理程序將傳遞SyntheticEvent實例,該實例是React跨瀏覽器本機事件的跨瀏覽器包裝器。這些綜合事件具備與您慣用的本機事件相同的界面,除了它們在全部瀏覽器中的工做方式相同。

有點有趣的是,React實際上並未將事件附加到子節點自己。React將使用單個事件偵聽器在頂層偵聽全部事件。這對性能有好處,也意味着React在更新DOM時無需擔憂跟蹤事件監聽器。

🔗 資料來源:tylermcginnis.com
🔗 參考資料:https://www.cnblogs.com/xiang...

Q5:state 和 props有什麼區別?

難度:⭐⭐

state 和 props都是普通的JavaScript對象。儘管它們二者都具備影響渲染輸出的信息,但它們在組件方面的功能不一樣。即

  • props是一個從外部傳進組件的參數,主要做爲就是從父組件向子組件傳遞數據,它具備可讀性和不變性,只能經過外部組件主動傳入新的props來從新渲染子組件,不然子組件的props以及展示形式不會改變。
  • state的主要做用是用於組件保存、控制以及修改本身的狀態,它只能在constructor中初始化,它算是組件的私有屬性,不可經過外部訪問和修改,只能經過組件內部的this.setState來修改,修改state屬性會致使組件的從新渲染。

🔗 資料來源: https : //github.com/sudheerj

🔗 參考資料:https://stackoverflow.com/que...

Q6:如何建立refs?

難度:⭐⭐

Refs 是使用 React.createRef() 方法建立的,並經過 ref 屬性添加到 React 元素上。爲了在整個組件中使用refs,只需將 ref 分配給構造函數中的實例屬性

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }
  render() {
    return <div ref={this.myRef} />;
  }
}

和:

class UserForm extends Component {
  handleSubmit = () => {
    console.log("Input Value is: ", this.input.value)
  }
  render () {
    return (
      <form onSubmit={this.handleSubmit}>
        <input
          type='text'
          ref={(input) => this.input = input} /> // Access DOM input in handle submit
        <button type='submit'>Submit</button>
      </form>
    )
  }
}

咱們還能夠藉助閉包在功能組件中使用它。

🔗 資料來源: github.com/sudheerj

🔗 參考資料:https://segmentfault.com/a/11...

Q7:什麼是高階組件?

難度:⭐⭐

高階組件就是一個函數,且該函數接受一個組件做爲參數,並返回一個新的組件。基本上,這是從React的組成性質派生的一種模式,咱們稱它們爲「純」組件, 由於它們能夠接受任何動態提供的子組件,但它們不會修改或複製其輸入組件的任何行爲。

const EnhancedComponent = higherOrderComponent(WrappedComponent);
  • 高階組件(HOC)是 React 中用於複用組件邏輯的一種高級技巧
  • 高階組件的參數爲一個組件返回一個新的組件
  • 組件是將 props 轉換爲 UI,而高階組件是將組件轉換爲另外一個組件

🔗 資料來源: github.com/sudheerj

🔗 參考資料:https://css-tricks.com/what-a...

Q8:constructor中super與props參數一塊兒使用的目的是什麼?

難度:⭐⭐

在調用方法以前,子類構造函數沒法使用this引用super()

在ES6中,在子類的constructor中必須先調用super才能引用this

constructor中可使用this.props

使用props:

class MyComponent extends React.Component {
    constructor(props) {
        super(props);
        console.log(this.props);  // Prints { name: 'sudheer',age: 30 }
    }
}

不使用props:

class MyComponent extends React.Component {
    constructor(props) {
        super();
        console.log(this.props); // Prints undefined
        // But Props parameter is still available
        console.log(props); // Prints { name: 'sudheer',age: 30 }
    }

    render() {
        // No difference outside constructor
        console.log(this.props) // Prints { name: 'sudheer',age: 30 }
    }
}

上面的代碼片斷揭示了this.props行爲僅在構造函數中有所不一樣。外部構造函數相同。

🔗 資料來源: github.com/sudheerjhttps://www.fullstack.cafe/Re...

Q9:什麼是受控組件?

難度:⭐⭐⭐

在HTML當中,像<input>,<textarea>, 和 <select>這類表單元素會維持自身狀態,並根據用戶輸入進行更新。但在React中,可變的狀態一般保存在組件的狀態屬性中,而且只能用 setState() 方法進行更新。

非受控組件

非受控組件,即組件的狀態不受React控制的組件,例以下邊這個
import React, { Component } from 'react';
import ReactDOM from 'react-dom';

class Demo1 extends Component {
    render() {
        return (
            <input />
        )
    }
}

ReactDOM.render(<Demo1/>, document.getElementById('content'))
在這個最簡單的輸入框組件裏,咱們並無干涉input中的value展現,即用戶輸入的內容都會展現在上面。若是咱們經過props給組件設置一個初始默認值,defaultValue屬性是React內部實現的一個屬性,目的相似於input的placeholder屬性。
ps: 此處若是使用value代替defaultValue,會發現輸入框的值沒法改變

受控組件

一樣的,受控組件就是組件的狀態受React控制。上面提到過,既然經過設置input的value屬性, 沒法改變輸入框值,那麼咱們把它和state結合在一塊兒,再綁定onChange事件,實時更新value值就好了。
class Demo1 extends Component {
    constructor(props) {
        super(props);
        this.state = {
            value: props.value
        }
    }

    handleChange(e) {
        this.setState({
            value: e.target.value
        })
    }

    render() {
        return (
            <input value={this.state.value} onChange={e => this.handleChange(e)}/>
        )
    }
}

🔗 資料來源: github.com/Pau1fitz

🔗 參考資料:https://www.php.cn/js-tutoria...

Q10:如下使用React.createElement的等價項是什麼?

難度:⭐⭐⭐

問題

const element = (
  <h1 className="greeting">
    Hello, world!
  </h1>
);

如下等同於什麼使用React.createElement

const element = React.createElement(
  'h1',
  {className: 'greeting'},
  'Hello, world!'
);

🔗 資料來源: github.com/Pau1fitz

Q11:什麼是JSX?

難度:⭐⭐⭐

JSX即JavaScript XML。一種在React組件內部構建標籤的類XML語法。JSX爲react.js開發的一套語法糖,也是react.js的使用基礎。React在不使用JSX的狀況下同樣能夠工做,然而使用JSX能夠提升組件的可讀性,所以推薦使用JSX。

class MyComponent extends React.Component {
  render() {
    let props = this.props;  
    return (
      <div className="my-component">
      <a href={props.url}>{props.name}</a>
      </div>
    );
  }
}

優勢:

1.容許使用熟悉的語法來定義 HTML 元素樹;

2.提供更加語義化且移動的標籤;

3.程序結構更容易被直觀化;

4.抽象了 React Element 的建立過程;

5.能夠隨時掌控 HTML 標籤以及生成這些標籤的代碼;

6.是原生的 JavaScript。

🔗 資料來源: codementor.io

🔗 參考資料:http://facebook.github.io/jsx/

Q12:爲何不直接更新state狀態?

難度:⭐⭐⭐

若是進行以下方式更新狀態,那麼它將不會從新渲染組件。

//Wrong
    This.state.message =」Hello world」;

而是使用setState()方法。它計劃對組件狀態對象的更新。狀態改變時,組件經過從新渲染作出響應

//Correct
 This.setState({message: ‘Hello World’});

注意:能夠分配狀態的惟一位置是構造函數。

🔗 資料來源: https : //github.com/sudheerj

Q13:ReactJS生命週期有哪些不一樣階段?

難度:⭐⭐⭐

React組件的生命週期分爲四個不一樣階段:

  1. 初始化:在此階段,react組件準備設置初始狀態和默認道具。
  2. 掛載: react組件已準備好掛載在瀏覽器DOM中。此階段涵蓋componentWillMountcomponentDidMount生命週期方法。
  3. 更新:在此階段,組件以兩種方式進行更新,即發送新道具和更新狀態。此階段涵蓋了shouldComponentUpdate,componentWillUpdate和componentDidUpdate生命週期方法。
  4. 卸載:在最後一個階段,不須要該組件,而且能夠從瀏覽器DOM上卸載該組件。此階段包括componentWillUnmount生命週期方法。

img

🔗 資料來源: github.com/sudheerj

Q14:ReactJS的生命週期方法是什麼?

難度:⭐⭐⭐
  • componentWillMount:在渲染以前執行,用於根組件中的應用程序級別配置。
  • componentDidMount:僅在客戶端的第一次渲染以後執行。 這是AJAX請求和DOM或狀態更新應該發生的地方。此方法也用於與其餘JavaScript框架以及任何延遲執行的函數(如setTimeoutsetInterval)進行集成,在這裏使用它來更新狀態,以便咱們能夠觸發其餘生命週期方法。
  • componentWillReceiveProps:只要在另外一個渲染被調用以前更新props就被調用。 當咱們更新狀態時,從setNewNumber觸發它。
  • shouldComponentUpdate:肯定是否將更新組件。默認狀況下,它返回true。若是您肯定組件在狀態或道具更新後不須要渲染,則能夠返回false值。這是提升性能的好地方,由於若是組件收到新的道具,它能夠防止從新渲染。
  • componentWillUpdate:在由shouldComponentUpdate確認返回正值的優勢和狀態更改時,在從新渲染組件以前執行。
  • componentDidUpdate:一般用於更新DOM以響應屬性或狀態更改。
  • componentWillUnmount:它將用於取消任何傳出的網絡請求,或刪除與該組件關聯的全部事件偵聽器。

🔗 資料來源: github.com/sudheerjhttps://www.fullstack.cafe/Re...

Q15:React中的這三個點(...)是作什麼的?

難度:⭐⭐⭐

...在此React(使用JSX)代碼中作什麼?它叫什麼?

<Modal {...this.props} title='Modal heading' animation={false}>

擴展傳值符號。它是在ES2018中添加的(數組/可迭代對象的傳播較早,ES2015)。

例如,若是this.props包含a:1和b:2,則

<Modal {...this.props} title='Modal heading' animation={false}>

與如下內容相同:

<Modal a={this.props.a} b={this.props.b} title='Modal heading' animation={false}>

擴展符號不只適用於該用例,並且對於建立具備現有對象的大多數(或所有)屬性的新對象很是方便-在更新狀態時會遇到不少問題,由於您沒法修改狀態直:

this.setState(prevState => {
    return {foo: {...prevState.foo, a: "updated"}};
});

🔗 資料來源: stackoverflow.com

Q16:使用React Hooks有什麼優點?

難度:⭐⭐⭐

hooks 是react 16.8 引入的特性,他容許你在不寫class的狀況下操做state 和react的其餘特性。
hooks 只是多了一種寫組件的方法,使編寫一個組件更簡單更方便,同時能夠自定義hook把公共的邏輯提取出來,讓邏輯在多個組件之間共享。

Hook 是什麼

Hook 是什麼? Hook 是一個特殊的函數,它可讓你「鉤入」 React 的特性。例如,useState 是容許你在 React 函數組件中添加 state 的 Hook。稍後咱們將學習其餘 Hook。

何時我會用 Hook? 若是你在編寫函數組件並意識到須要向其添加一些 state,之前的作法是必須將其它轉化爲 class。如今你能夠在現有的函數組件中使用 Hook。

ReactHooks的優勢

  • 無需複雜的DOM結構
  • 簡潔易懂

🔗 資料來源: hackernoon.com

Q17:React中的useState?

難度:⭐⭐⭐

案例:

import { useState } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  )
}

語法:

function useState<S>(initialState: S | (() => S)): [S, Dispatch<SetStateAction<S>>];

其中 state 是他的值, setState 是用來設置值的函數, initialState 是初始值

useState-initialState

該初始值能夠接受任何參數,可是記得當他接受爲一個函數時,就變成了Lazy initialization (延遲初始化)
該函數返回值即爲initialState

const [count, setCount] = useState(0);

const [count, setCount] = useState(()=>0);
// 這兩種初始化方式 是相等的,可是在函數爲初始值時會被執行一次

const [count, setCount] = useState(()=>{
    console.log('這裏只會在初始化的時候執行')
    // class 中的 constructor 的操做均可以移植到這裏
    return 0
});
// 當第一次執行完畢後 就和另外一句的代碼是相同的效果了

useState-setState

也許不少人 在使用 class 的 setState 時候,會常用他的回調函數,
可是這裏很遺憾,他只接受新的值,若是想要對應的回調,可使用useEffect,這個問題等會會提供一個跳轉連接

Q18:React中的StrictMode是什麼?

難度:⭐⭐⭐

React的StrictMode是一種幫助程序組件,能夠幫助您編寫更好的react組件,您可使用包裝一些組件,<StrictMode />而且基本上能夠:

  • 驗證內部組件是否遵循某些推薦作法,若是不在控制檯中,則會發出警告。
  • 驗證不同意使用的方法,若是使用了嚴格模式,則會在控制檯中警告您。
  • 經過識別潛在風險來幫助您預防某些反作用。

🔗 參考資料:http://react.html.cn/docs/str...

Q19:爲何類方法須要綁定?

難度:⭐⭐⭐

在JavaScript中,this的值取決於當前上下文。在React類的組件方法中,開發人員一般但願它引用組件的當前實例,所以有必要這些方法綁定到該實例。一般,這是在構造函數中完成的,例如:

class SubmitButton extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isFormSubmitted: false
    };
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleSubmit() {
    this.setState({
      isFormSubmitted: true
    });
  }

  render() {
    return (
      <button onClick={this.handleSubmit}>Submit</button>
    )
  }
}

🔗 資料來源: toptal.com

Q20:描述Flux與MVC?

難度:⭐⭐⭐⭐

傳統的MVC模式在分離數據(模型),UI(視圖)和邏輯(控制器)的關注方面效果很好,可是MVC架構常常遇到兩個主要問題:

  • 數據流定義不佳:跨視圖進行的級聯更新一般會致使糾結的事件網,難以調試。
  • 缺少數據完整性:能夠從任何地方對模型數據進行突變,從而在整個UI上產生不可預測的結果。

使用Flux模式,複雜的UI再也不受到級聯更新的困擾。任何給定的React組件都將可以根據商店提供的數據重建其狀態。Flux模式還經過限制對共享數據的直接訪問來加強數據完整性。

🔗 資料來源: codementor.iohttps://www.fullstack.cafe/Re...

Q21:React context是什麼?

難度:⭐⭐⭐⭐

React文檔官網並未對Context給出「是什麼」的定義,更可能是描述使用的Context的場景,以及如何使用Context

官網對於使用Context的場景是這樣描述的:

In Some Cases, you want to pass data through the component tree without having to pass the props down manuallys at every level. you can do this directly in React with the powerful "context" API.

簡單說就是,當你不想在組件樹中經過逐層傳遞props或者state的方式來傳遞數據時,可使用Context來實現跨層級的組件數據傳遞。

image-20191113183434115

使用props或者state傳遞數據,數據自頂下流。

image-20191113183459729

使用Context,能夠跨越組件進行數據傳遞。

🔗 資料來源: github.com/WebPredict

Q22:React Fiber是什麼?

難度:⭐⭐⭐⭐

React Fiber 並非所謂的纖程(微線程、協程),而是一種基於瀏覽器的單線程調度算法,背後的支持 API 是大名鼎鼎的:requestIdleCallback。

Fiberl是一種將 recocilation (遞歸 diff),拆分紅無數個小任務的算法;它隨時可以中止,恢復。中止恢復的時機取決於當前的一幀(16ms)內,還有沒有足夠的時間容許計算。

相關文章
相關標籤/搜索