React 之 State Hook 與 Custom Hook

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

内容简介:以萬年老梗 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


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

查看所有标签

猜你喜欢:

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

京东平台运营攻略(全彩)

京东平台运营攻略(全彩)

京东商学院 / 电子工业出版社 / 2015-5 / 69.00元

2014 年年末,京东POP 开放平台的入驻商家已超过6 万,京东平台被广泛关注和认可的同时,在电商江湖中仍颇具神秘色彩。面对碎片化的信息,京东的店铺经营者及希望入驻京东的准商家们,对于在京东如何利用丰富的各类平台资源,搭建并运营京东店铺,一直很难找到全面而系统的资料。 《京东平台运营攻略(全彩)》由京东官方出品,动员了京东内部涉及第三方店铺业务线的众多部门,由多位业务精英参与撰写,保证了内......一起来看看 《京东平台运营攻略(全彩)》 这本书的介绍吧!

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

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

RGB CMYK 互转工具