react入門知識點梳理,生命週期講解

react 基礎

JSX

  • JSX是一個 JavaScript 的語法擴展,可以很好地描述 UI 應該呈現出它應有交互的本質形式。
  • React DOM 在渲染所有輸入內容之前,默認會進行轉義。它可以確保在你的應用中,永遠不會注入那些並非自己明確編寫的內容。所有的內容在渲染之前都被轉換成了字符串。
  • JSX 裏的 class 變成了 className

元素

  • 元素是構成 React 應用的最小磚塊。
  • React 元素是創建開銷極小的普通對象。React DOM 會負責更新 DOM 來與 React 元素保持一致。
  • 組件是由元素構成的。

組件

組件名稱必須以大寫字母開頭(React 會將以小寫字母開頭的組件視爲原生 DOM 標籤)

  • 函數組件:
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}
  • class組件
class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

props

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

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

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

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

State

  • 使用this.setState()設置state的值
  • this.setState()可能是異步的
  • 調用this.setState()的時候,React 會把你提供的對象合併到當前的 state。

數據流

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

生命週期

在 V16 版本中引入了 Fiber 機制。這個機制一定程度上的影響了部分生命週期的調用,並且也引入了新的 2 個 API 來解決問題。(Fiber 本質上是一個虛擬的堆棧幀,新的調度器會按照優先級自由調度這些幀,從而將之前的同步渲染改成了異步渲染,在不影響體驗的情況下去分段計算更新。在之前的版本中,如果你擁有一個很複雜的複合組件,然後改動了最上層組件的 state,那麼調用棧可能會很長,調用棧過長,再加上中間進行了複雜的操作,就可能導致長時間阻塞主線程,帶來不好的用戶體驗。Fiber 就是爲了解決該問題而生。)

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

  // 用於替換 `componentWillReceiveProps` ,該函數會在初始化和 `update` 時被調用
  // 因爲該函數是靜態函數,所以取不到 `this`
  // 如果需要對比 `prevProps` 需要單獨在 `state` 中維護
  static getDerivedStateFromProps(nextProps, prevState) {}

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

  // 組件掛載後調用
  // 可以在該函數中進行請求或者訂閱
  componentDidMount() {}

  // 用於替換 componentWillUpdate ,該函數會在 update 後 DOM 更新前被調用
  // 用於讀取最新的 DOM 數據。
  getSnapshotBeforeUpdate() {}

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

  // 組件銷燬後調用
  componentDidUnMount() {}

  // 組件更新後調用
  componentDidUpdate() {}

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

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

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

  // 以下函數不建議使用
  UNSAFE_componentWillMount() {}
  UNSAFE_componentWillUpdate(nextProps, nextState) {}
  UNSAFE_componentWillReceiveProps(nextProps) {}
}

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

  • Reconciliation 階段:

    • componentWillMount
    • componentWillReceiveProps
    • shouldComponentUpdate
    • componentWillUpdate
  • Commit 階段:

    • componentDidMount
    • componentDidUpdate
    • componentWillUnmount

因爲 reconciliation 階段是可以被打斷的,所以 reconciliation 階段會執行的生命週期函數就可能會出現調用多次的情況,從而引起 Bug。所以對於 reconciliation 階段調用的幾個函數,除了 shouldComponentUpdate 以外,其他都應該避免去使用。

事件處理

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

爲JSX內時間綁定this的幾種方式:

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

key

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

受控組件

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

進階

redux-adcanve

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章