[譯] React v16.8: 含有Hook的版本

司南free發表於2019-02-15

原文出處:React v16.8: The One With Hooks February 06, 2019 by Dan Abramov

伴隨 React 16.8,React Hook可以在穩定版本中使用!


什麼是 Hook?

Hook 可以讓我們不用寫一個 class 就能使用 state 和其他的 React 特性。我們也可以構建我們自己的 Hook 來在元件之間共享可重複使用的有狀態邏輯。 如果您之前從未聽說 Hooks,您可能對下列這些資源感興趣:

您現在沒必要一定要學習 Hook 。 Hook 並沒有突破性的改變,而且我們也沒有打算 React 中移除 class。這篇Hook FAQ描述了逐步採用的策略。


無需大規模重寫

我們不推薦重寫您已經存在的應用,以便一夜之間就使用上 Hooks。相反,我們更建議您嘗試在一些新的元件中使用 Hooks,並且請讓我們瞭解到您的使用感受。使用 Hook 的程式碼會與現存使用 class 的程式碼並肩在一起工作。

現在可以使用 Hook 了嗎?

當然!從 16.8.0 開始,React 包含了 React Hook 的穩定實現來用於:

  • React DOM
  • React DOM Server
  • React Test Renderer
  • React Shallow Renderer 請注意,要啟用 Hooks,所有的 React 包均需要升級到 16.8.0 或者更高版本。 如果忘記升級,不能使用 Hooks,比如 React DOM。

React Native 將會在 0.59 釋出版本中得到支援。


工具支援

React DevTools 目前支援 React Hooks。在最新的 Flow 和 TypeScript 對 React 的定義中也同樣支援。我們強烈建議使用一條名為 eslint-plugin-react-hooks 的新檢查規則,來強制實現 Hook 的最佳實踐。很快它也會預設包含進 Create React App 中。


下一步呢?

我們已經在最近釋出的 React Roadmap 中,描述了我們接下來幾個月的計劃。

請注意 React Hook 還沒有涵蓋 class 的所有用例,但是差不多了快完成了

目前,只有 getSnapshotBeforeUpdate()componentDidCatch() 這倆方法沒有相對應的 Hook API,而且它們的生命週期相對來說比較特殊少見。如果您需要,您應該可以在您寫的大多數新程式碼中使用 Hooks。

儘管 Hook 還處於初步階段,React 社群已經使用 Hook 為動畫、表單、訂閱、與其他庫整合等方面,創作了很多有意思的示例指南手冊。Hooks 使得程式碼複用更加簡單,幫助我們用更加簡潔的方式寫出元件,以提供更好的使用者體驗,這讓我們感到很興奮。我們等不及要看到您下一次的創作!


測試 Hook

我們在釋出版中新增了一個名為 ReactTestUtils.act() 的新 API。它可以確保測試中的行為與瀏覽器中的行為更緊密地匹配。我們建議將任何渲染和觸發元件更新的程式碼包裝進 act() 呼叫。測試庫也可以用它包裝它們的API(例如,react-testing-libraryrenderfireEvent 實用工具就是這樣做的)。

例如,此頁面的計數器可以像這樣進行測試:

import React from 'react';
import ReactDOM from 'react-dom';
import { act } from 'react-dom/test-utils';
import Counter from './Counter';

let container;

beforeEach(() => {
  container = document.createElement('div');
  document.body.appendChild(container);
});

afterEach(() => {
  document.body.removeChild(container);
  container = null;
});

it('can render and update a counter', () => {
  // Test first render and effect
  act(() => {
    ReactDOM.render(<Counter />, container);
  });
  const button = container.querySelector('button');
  const label = container.querySelector('p');
  expect(label.textContent).toBe('You clicked 0 times');
  expect(document.title).toBe('You clicked 0 times');

  // Test second render and effect
  act(() => {
    button.dispatchEvent(new MouseEvent('click', {bubbles: true}));
  });
  expect(label.textContent).toBe('You clicked 1 times');
  expect(document.title).toBe('You clicked 1 times');
});
複製程式碼

如果打算測試自定義的 Hooks,可以通過在測試中建立一個元件並使用它的 Hook 來實現,然後您就可以測試您寫的 Hook 了。

為了減少樣板,建議使用 react-testing-library 來進行測試,該庫是為鼓勵編寫測試用例而設計的。


感謝

感謝所有在 Hook RFC 中進行評論來分享自己的反饋資訊的同學。我們已經閱讀了你們的所有評論意見,並在其基礎上為最終的 API 做了些許調整。


安裝

React

React v16.8.0 在 npm 上已可以使用。

使用 Yarn 來安裝 React 16,執行命令:

yarn add react@^16.8.0 react-dom@^16.8.0
複製程式碼

使用 npm 來安裝 React 16,執行命令:

npm install --save react@^16.8.0 react-dom@^16.8.0
複製程式碼

同時也通過 CDN 提供React 的 UMD 構建版本:

<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
複製程式碼

有關詳細安裝說明,請參閱文件

用於 React Hook 的 ESLint 外掛

注意: 如上所述,強烈建議您使用eslint-plugin-react-hooks 規則。 如果正在使用 Create React App,而不是手動配置 ESLint,建議等待下一個版本的 react-scripts,即將釋出並且會包含這條規則。

假定您已經安裝過了 ESLint,執行命令:

# npm
npm install eslint-plugin-react-hooks@next --save-dev

# yarn
yarn add eslint-plugin-react-hooks@next --dev
複製程式碼

然後,新增下面的內容到 ESLint 配置中:

{
  "plugins": [
    // ...
    "react-hooks"
  ],
  "rules": {
    // ...
    "react-hooks/rules-of-hooks": "error"
  }
}
複製程式碼

相關文章