React 之 State Hook 與 Custom Hook

栏目: IOS · Android · 发布时间: 6年前

内容简介:以萬年老梗 counter 來看 State Hook 如何改變 React 寫法,並使用 Custom Hook 加以重構。React 16.8.114 行

以萬年老梗 counter 來看 State Hook 如何改變 React 寫法,並使用 Custom Hook 加以重構。

Version

React 16.8.1

Class Component

App.js

import React, { Component } from 'react';

class App extends Component {
  state = {
    count: 0,
  }

  addCount = () => {
    this.setState({
      count: this.state.count + 1
    });
  }

  render() {
    return (
      <div>
        <button onClick={ this.addCount }>+</button>
        <div>{ this.state.count }</div>
      </div>
    );
  }
}

export default App;

14 行

render() {
  return (
    <div>
      <button onClick={ this.addCount }>+</button>
      <div>{ this.state.count }</div>
    </div>
  );
}

傳統 HTML 的 JSX 要寫在 render() 內,且必須使用 this 才能抓到 state 與 method。

第 4 行

state = {
  count: 0,
}

宣告 state object 儲存 count state。

第 8 行

addCount = () => {
  this.setState({
    count: this.state.count + 1
  });
}

定義 click 的 event handler: addCount() ,使用 setState() 寫入新的 state。

Class Component 寫法遵循 OOP 風格:使用 side effect 更改 state,且大量使用 thismethod

Function Component

App.js

import React, { useState } from 'react';

const App = () => {
  const [count, setCount] = useState(0);
  const addCount = () => setCount(count + 1);

  return (
    <div>
      <button onClick={ addCount }>+</button>
      <div>{ count }</div>
    </div>
  );
};

export default App;

App 由 class 變成 function。

第 7 行

return (
  <div>
    <button onClick={ addCount }>+</button>
    <div>{ count }</div>
  </div>
);

不再需要 render() ,只需 return JSX 即可。

也由於 state 與 method 都宣告在 App() 內,連 this 也不需要了。

第 4 行

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

React 提供了 useState() hook,傳進 state 的初始值,也就是 0 ,回傳兩個值,一個為 state,另外一個為 state 的 setter function,習慣命名為 setXXX()

第 5 行

const addCount = () => setCount(count + 1);

定義 click 的 event handler: addCount() ,使用 useState() hook 提供的 setCount() 寫入新的 state。

Function Component 寫法遵循 FP 風格:不使用 side effect 更改 state,也沒有使用 thismethod ,全都是一進一出的 Pure Function,且行數從 24 行精簡到 15 行

Custom Hook

Q:若將來 App() 太大要重構,或其他 component 要重複使用這段邏輯該怎麼辦 ?

counter.js

import { useState } from 'react';

export const useCount = () => {
  const [count, setCount] = useState(0);
  const addCount = () => setCount(count + 1);

  return [
    count,
    addCount,
  ];
}

我們將 count state 與 addCount() 抽成 useCount() hook,單獨放在 counter module 中。

由於 JSX 需要的只有 count state 最後結果與 addCount() ,最後再將這兩個以 array 方式傳回。

React 官方建議 custom hook 都以 use 開頭。

App.js

import React from 'react';
import { useCount } from './counter';

const App = () => {
  const [count, addCount] = useCount();
  
  return (
    <div>
      <button onClick={ addCount }>+</button>
      <div>{ count }</div>
    </div>
  );
};

export default App;

App() 只要接收 useCount() hook 所傳回的值即可。

我們可以發現由於 Function Component 的 Hook 寫法,因為沒有 side effect,都是 Pure Function,所以特別容易重構,只要簡單的 Extract Function,然後搬到其他 module 即可

Conclusion

  • 有了 State Hook,使得原本必須在 Class Component 才能有的 state,目前在 Function Component 也能達成
  • 由於 Function Component 都是 Pure Function,因此特別容易重構成 Custom Hook
  • Component 間牽涉 state 的邏輯若有重複,只要簡單抽成 Custom Hook 再 import 進來即可,不必再使用 render propshigher-order component

Sample Code

完整範例可以在我的 GitHub 上找到

Reference

Reed Barger, React Hooks

React , Using the State Hook

React , Building Your Own Hooks


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Art of Computer Programming, Volumes 1-3 Boxed Set

The Art of Computer Programming, Volumes 1-3 Boxed Set

Donald E. Knuth / Addison-Wesley Professional / 1998-10-15 / USD 199.99

This multivolume work is widely recognized as the definitive description of classical computer science. The first three volumes have for decades been an invaluable resource in programming theory and p......一起来看看 《The Art of Computer Programming, Volumes 1-3 Boxed Set》 这本书的介绍吧!

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具