React-Hooks 面試解答

最近看到一個關於 React 的面試題,是京東技術三面的題目,感受頗有意思,一塊兒來看看:react

React 加入 Hooks 的意義是什麼?或者說一下爲何 React 要加入Hooks 這一特性?最後舉例說一下 Hooks 的基本實現原理;面試

首先,咱們看一下典型的兩個 Hooks 的基本使用,直接看代碼,這裏就不細說了;編程

useState 基本使用:數組

// 引入 useState
import React, { useState } from 'react'

function App() {
  // 使用
  const [count, setCount] = useState(1);
  return (
    <div> <h2> useState </h2> <p>{count}</p> {/* 調用 setCount方法 */} <button onClick={() => setCount(count + 1)}> 加1 </button> </div>
  )
}

export default App

複製代碼

useEffect :markdown

import React, { useState, useEffect } from 'react'
import ReactDom from 'react-dom'

function App() {
  const [count, setCount] = useState(1)

  // 組件掛載完成以後執行 && 組件數據更新完成以後執行
  // useEffect(() => {
  // console.log('666')
  // })


  // 組件掛載完成以後執行
  // useEffect(()=>{
  // console.log(678)
  // },[])


  // 組件被卸載以前執行 (引入react-dom進行卸載測試)
  useEffect(()=>{
    return ()=>{
      console.log('組件被卸載了')
    }
  })


  return (
    <div> <h2>useEffect</h2> <p>{count}</p> <button onClick={() => setCount(count + 1)}> 加1 </button> {/* 卸載組件 */} <button onClick={()=>ReactDom.unmountComponentAtNode(document.getElementById('root'))}>卸載組件</button> </div>
  )
}

export default App

複製代碼

回到前面的問題,其實這樣的問題並無什麼標準答案,可是咱們能夠換位思考,站在面試官的角度想一下,爲何會問這樣的問題?無非就是想考察咱們對 Hooks 最基本的使用狀況以及對 Hooks 設計理念的我的思考; 其實在 React 官方文檔中,已經給出了答案,奈何不少人就是不看文檔啊; Hook 簡介 – React (docschina.org)dom

image-20210111153114693.png

文檔中的 「動機」 就很好的解釋了爲何 React 要加入 Hooks 特性,總結來講就是三個基本要素: 1:組件之間的邏輯狀態難以複用; 2:大型複雜的組件很難拆分; 3:Class 語法的使用不友好;函數式編程

總的來講,實際上就是類組件在多年的應用實踐中,發現了不少沒法避免問題而又難以解決,而相對類組件,函數組件又太過於簡陋,好比,類組件能夠訪問生命週期方法,函數組件不能;類組件中能夠定義並維護 state(狀態),而函數組件不能夠;類組件中能夠獲取到實例化後的 this,並基於這個 this 作各類各樣的事情,而函數組件不能夠;函數

可是,函數式編程方式在JS中確實比 Class 的面向對象方式更加友好直觀,那麼只要可以將函數的組件能力補齊,也就解決了上面的問題,而若是直接修改函數組件的能力,勢必會形成更大的成本,最好的方式就是開放對應接口進行調用,非侵入式引入組件能力,也就是咱們如今看到的 Hooks 了;學習

明白了與緣由,面試中的問題也就迎刃而解了,基本思路就是先闡述在沒有 Hooks 的時候,類組件有哪些問題,函數組件有哪些不足,而 Hooks 就是解決這些問題出現的;這也就是 Hooks 出現的意義了,那麼接着,咱們再來解答下一個問題,Hooks 的設計理念是什麼呢? 咱們先用代碼來模仿一個基本的 Hooks 的實現過程,重寫 useState :測試

import React from 'react'
// 導入dom,用於更新組件
import ReactDom from 'react-dom'

let state
function useState(initState) {
  // 判斷state 是不是初始化
  state = state ? state : initState
  function setState(newState) {
    // 更新數據
    state = newState
    // 調用函數,更新組件
    render()
  }

  return [state, setState]
}

// 從新渲染組件
function render() {
  ReactDom.render(<App />, document.getElementById('root'))
}

function App() {
  // 使用自定義 useState 
  const [count, setCount] = useState(1);

  return (
    <div> <p>{count}</p> <button onClick={() => setCount(count + 1)}>加1</button> </div>
  )
}

export default App

複製代碼

Rudi Yardley 在 2018 年的時候寫過一篇文章 《React hooks: not magic, just arrays》,詳細地闡釋了它的設計原理,感興趣的話能夠找來看一下,上面案例,其實就是文章中用到的,經過在函數中調用 useState 會返回當前狀態與更新狀態的函數。count 的初始值是 1,而後,經過 useState 賦值初始值,而後獲取當前狀態 state 與函數 setState。那麼在點擊按鈕時調用 setCount,修改 count 的值。本質上 state hook 替代了類組件中 setState 的做用。

通常狀況下,一段激情的闡述以後都是要上價值的,因此,咱也來一段;

React 團隊固然清楚,新加一個全新的概念,對咱們開發者來講是一個很高的學習成本,所以官方爲好奇的讀者準備了 詳細的徵求意見文檔,在文檔中用更多細節深刻討論了 React 推動這件事的動機,也在具體設計決策和相關先進技術上提供了額外的視角。

最重要的是,Hook 和現有代碼能夠同時工做,你能夠漸進式地使用他們。 不用急着遷移到 Hook。咱們建議避免任何「大規模重寫」,尤爲是對於現有的、複雜的 class 組件。開始「用 Hook 的方式思考」前,須要作一些思惟上的轉變。

相關文章
相關標籤/搜索