01.react入門必備,知識點梳理,生命周期全講解

react 基礎(chǔ)

JSX

  • JSX是一個 JavaScript 的語法擴(kuò)展,可以很好地描述 UI 應(yīng)該呈現(xiàn)出它應(yīng)有交互的本質(zhì)形式。
  • React DOM 在渲染所有輸入內(nèi)容之前,默認(rèn)會進(jìn)行轉(zhuǎn)義。它可以確保在你的應(yīng)用中,永遠(yuǎn)不會注入那些并非自己明確編寫的內(nèi)容。所有的內(nèi)容在渲染之前都被轉(zhuǎn)換成了字符串。
  • JSX 里的 class 變成了 className
深入了解:

JSX 僅僅只是 React.createElement(component, props, ...children) 函數(shù)的語法糖。

如下JSX代碼:

<MyButton color="blue" shadowSize={2}>
  Click Me
</MyButton>

會編譯為:

React.createElement(
  MyButton,
  {color: 'blue', shadowSize: 2},
  'Click Me'
)

元素

  • 元素是構(gòu)成 React 應(yīng)用的最小磚塊。
  • React 元素是創(chuàng)建開銷極小的普通對象。React DOM 會負(fù)責(zé)更新 DOM 來與 React 元素保持一致。
  • 組件是由元素構(gòu)成的。
  • false, null, undefined, true 是合法的子元素。但它們并不會被渲染。

以下的 JSX 表達(dá)式渲染結(jié)果相同:

<div />

<div></div>

<div>{false}</div>

<div>{null}</div>

<div>{undefined}</div>

<div>{true}</div>

組件

組件名稱必須以大寫字母開頭(React 會將以小寫字母開頭的組件視為原生 DOM 標(biāo)簽)

  • 函數(shù)組件(以前稱之為無狀態(tài)組件,但Hook出來之后叫為函數(shù)組件):
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}
  • class組件
class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

props

當(dāng) React 元素為用戶自定義組件時,它會將 JSX 所接收的屬性(attributes)轉(zhuǎn)換為單個對象傳遞給組件,這個對象被稱之為 “props”。組件無論是使用函數(shù)聲明還是通過 class 聲明,都決不能修改自身的 props

// 這段代碼會在頁面上渲染 “Hello, Sara”
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

const element = <Welcome name="Sara" />;
ReactDOM.render(
  element,
  document.getElementById('root')
);

//上段代碼渲染時發(fā)生了什么:
  1. 我們調(diào)用 ReactDOM.render() 函數(shù),并傳入 <Welcome name="Sara" /> 作為參數(shù)。
  2. React 調(diào)用 Welcome 組件,并將 {name: 'Sara'} 作為 props 傳入。
  3. Welcome 組件將 <h1>Hello, Sara</h1> 元素作為返回值。
  4. React DOM 將 DOM 高效地更新為 <h1>Hello, Sara</h1>。

有多種方式可以在 JSX 中指定 props。

  • JavaScript 表達(dá)式作為 Props
  • 字符串字面量
  • props 默認(rèn)值為true

State

  • 使用this.setState()設(shè)置state的值
  • this.setState()可能是異步的
  • 調(diào)用this.setState()的時候,React 會把你提供的對象合并到當(dāng)前的 state。

數(shù)據(jù)流

react是單向數(shù)據(jù)流,任何的 state 總是所屬于特定的組件,而且從該 state 派生的任何數(shù)據(jù)或 UI 只能影響樹中“低于”它們的組件。

生命周期

在 V16 版本中引入了 Fiber 機制。這個機制一定程度上的影響了部分生命周期的調(diào)用,并且也引入了新的 2 個 API 來解決問題。(Fiber 本質(zhì)上是一個虛擬的堆棧幀,新的調(diào)度器會按照優(yōu)先級自由調(diào)度這些幀,從而將之前的同步渲染改成了異步渲染,在不影響體驗的情況下去分段計算更新。在之前的版本中,如果你擁有一個很復(fù)雜的復(fù)合組件,然后改動了最上層組件的 state,那么調(diào)用??赡軙荛L,調(diào)用棧過長,再加上中間進(jìn)行了復(fù)雜的操作,就可能導(dǎo)致長時間阻塞主線程,帶來不好的用戶體驗。Fiber 就是為了解決該問題而生。)

class ExampleComponent extends React.Component {
  // 用于初始化 state
  constructor(props) {
    super(props)
    this.state = { hasError: false };
  }

  // 用于替換 `componentWillReceiveProps` ,該函數(shù)會在初始化和 `update` 時被調(diào)用
  // 因為該函數(shù)是靜態(tài)函數(shù),所以取不到 `this`, 如果需要對比 `prevProps` 需要單獨在 `state` 中維護(hù)
  // 它應(yīng)返回一個對象來更新 state
  static getDerivedStateFromProps(nextProps, prevState) {}

  // 判斷是否需要更新組件,多用于組件性能優(yōu)化
  shouldComponentUpdate(nextProps, nextState) {}

  // 組件掛載后調(diào)用
  // 可以在該函數(shù)中進(jìn)行請求或者訂閱
  componentDidMount() {}

  // 用于替換 componentWillUpdate ,該函數(shù)會在 update 后 DOM 更新前被調(diào)用
  // 用于讀取最新的 DOM 數(shù)據(jù)。
  getSnapshotBeforeUpdate() {}

  // 組件即將銷毀
  // 可以在此處移除訂閱,定時器等等
  componentWillUnmount() {}

  // 組件銷毀后調(diào)用
  componentDidUnMount() {}

  // 組件更新后調(diào)用
  componentDidUpdate() {}

  // 錯誤邊界 - 渲染備用 UI
  // 更新 state 使下一次渲染能夠顯示降級后的 UI
  // 注意錯誤邊界僅可以捕獲其子組件的錯誤,它無法捕獲其自身的錯誤
  static getDerivedStateFromError(error) {
    return { hasError: true };
  }

  // 錯誤邊界 - 打印錯誤信息
  // 你同樣可以將錯誤日志上報給服務(wù)器
  // 注意錯誤邊界僅可以捕獲其子組件的錯誤,它無法捕獲其自身的錯誤
  componentDidCatch(error, info) {
    console.log(error, info);
  }

  // 渲染組件函數(shù)
  render() {}

  // 以下函數(shù)不建議使用
  UNSAFE_componentWillMount() {}
  UNSAFE_componentWillUpdate(nextProps, nextState) {}
  // 接收到新的props時調(diào)用
  UNSAFE_componentWillReceiveProps(nextProps) {}
}

對于異步渲染,現(xiàn)在渲染有兩個階段:reconciliation 和 commit 。前者過程是可以打斷的,后者不能暫停,會一直更新界面直到完成。

  • Reconciliation 階段:
    • componentWillMount
    • componentWillReceiveProps
    • shouldComponentUpdate
    • componentWillUpdate
  • Commit 階段:
    • componentDidMount
    • componentDidUpdate
    • componentWillUnmount

因為 reconciliation 階段是可以被打斷的,所以 reconciliation 階段會執(zhí)行的生命周期函數(shù)就可能會出現(xiàn)調(diào)用多次的情況,從而引起 Bug。所以對于 reconciliation 階段調(diào)用的幾個函數(shù),除了 shouldComponentUpdate 以外,其他都應(yīng)該避免去使用。

V16.4以后生命周期圖解(不包含官方不建議使用的)

reactLifecycle.png

事件處理

  • React 事件的命名采用小駝峰式(camelCase),而不是純小寫。
  • 使用 JSX 語法時你需要傳入一個函數(shù)作為事件處理函數(shù),而不是一個字符串。

為JSX內(nèi)時間綁定this的幾種方式:

  • constructor內(nèi)處理:
constructor() {
  this.handleClick = this.handleClick.bind(this);
}
  • JSX內(nèi)使用bind:
<button onClick={this.handleClick.bind(this, id)}>Delete Row</button>
  • 箭頭函數(shù):
<button onClick={() => this.handleClick(id)}>Delete Row</button>

key

key 幫助 React 識別哪些元素改變了,比如被添加或刪除。因此你應(yīng)當(dāng)給數(shù)組中的每一個元素賦予一個確定的標(biāo)識。
key 只是在兄弟節(jié)點之間必須唯一

受控組件

使 React 的 state 成為“唯一數(shù)據(jù)源”。渲染表單的 React 組件還控制著用戶輸入過程中表單發(fā)生的操作。被 React 以這種方式控制取值的表單輸入元素就叫做受控組件。

非受控組件

表單數(shù)據(jù)將交由 DOM 節(jié)點來處理。使用非受控組件時如果想賦予組件一個初始值,但是不去控制后續(xù)的更新。 在這種情況下, 你可以指定一個 defaultValue 屬性,而不是 value。

<input type="file" /> 始終是一個非受控組件

進(jìn)階

redux-adcanve

原文git地址 覺得有用的話,來個star鼓勵,持續(xù)更新中。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 3. JSX JSX是對JavaScript語言的一個擴(kuò)展語法, 用于生產(chǎn)React“元素”,建議在描述UI的時候...
    pixels閱讀 2,983評論 0 24
  • 一、React的工作原理 1、UI = f(data){} UI 就是界面 ,這個界面就是函數(shù)執(zhí)行的結(jié)果,是按照函...
    it筱竹閱讀 1,309評論 0 4
  • 原教程內(nèi)容詳見精益 React 學(xué)習(xí)指南,這只是我在學(xué)習(xí)過程中的一些閱讀筆記,個人覺得該教程講解深入淺出,比目前大...
    leonaxiong閱讀 2,954評論 1 18
  • 作為一個合格的開發(fā)者,不要只滿足于編寫了可以運行的代碼。而要了解代碼背后的工作原理;不要只滿足于自己的程序...
    六個周閱讀 8,687評論 1 33
  • 今天的React題沒有太多的故事…… 半個月前出了248個Vue的知識點,受到很多朋友的關(guān)注,都強烈要求再出多些R...
    浪子神劍閱讀 10,246評論 6 106

友情鏈接更多精彩內(nèi)容