React Hooks 不完全指南

人生真正的本質(zhì)不是希望,而是意義。人總是會死的,希望總是會破滅。但,只要你認為你人生的每一天都是有意義的,你才能夠去面對你經(jīng)歷的所有苦難。

Photo by Ng?c Thu?n on Unsplash

React 前段時間發(fā)布了 Hooks 這個新的特性,雖然還只是個提案,但是很多人都表示很看好它,今天我們就來了解一下 React Hooks。

準備工作

我們先使用 create-react-app 新建一個項目:

$ npm install -g npx
$ npx create-react-app hooks

由于 React Hooks 還只是個 RFC 草案,所以我們還不能在正式版本中使用它,需要安裝對應(yīng)的 alpha 版本才可以:

$ cd  hooks
$ npm install -S react@16.7.0-alpha.2 react-dom@16.7.0-alpha.2
$ npm run start

一個簡單的例子

我們可以打開項目,在 /src 下新建一個 Counter.js 文件:

import React, { useState } from 'react';

export function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <h1>{count}</h1>
      <button onClick={() => setCount(count + 1)}>沒事走倆步</button>
    </div>
  )
}

怎么樣?是不是看出了點什么?讓我們把這個組件放到 App.js 下看看效果~

import { Counter } from './Counter'; 

class App extends Component {
  render() {
    return (
      <div className="App">
        <Counter />
      </div>
    )
  }
}

好吧,這其實就是個最簡單的計數(shù)器組件,并沒有什么了不起的。如果是在原來,我們會怎么寫呢?

import React from 'react'

export class AnotherCounter extends Component {
  constructor() {
    super()
    this.state = { count: 0 }
  }

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

  render() {
    return (
      <div>
        <h1>{this.state.count}</h1>
        <button onClick={ this.increment }>你跺你也麻</button>
      </div>
    )
  }
}

為了使用 state 我們必須使用 class component,所以你肯定已經(jīng)明白了——什么是 React Hooks?

Hooks let you use React features without writing a class!

哦!這個叫做「鉤子」的東西讓我們再也不用寫 class component 啦!

PS:也別擔心,React 官方并沒有不鼓勵使用類組件的意思,只是給我們多提供了一種寫組件的方式~

useState

好了,知道了 Hooks 是什么,讓我們再回過頭看看之前例子的代碼吧!你一定對這個 useState 感到很好奇,它是怎么做到讓 functional component 做到和 class component 一樣的事情的呢?

我們其實可以看到,在 useState 方法前面,我們使用了數(shù)組解構(gòu)的語法,其實 useState 也就給了我們兩個變量,我們其實可以隨便給它們命名,這個數(shù)組中的兩個變量是:

  1. 第一個變量是「狀態(tài)值」,它有點像 this.state
  2. 第二個變量是一個更新「狀態(tài)值」的方法,有點像 this.setState

然后,我們傳遞給 useState 方法的其實是我們想要的「初始狀態(tài)值」,在這里我們傳了一個 0 作為 count 的初始值,相當于在構(gòu)造函數(shù)中 this.state = { count: 0 } 的作用。

就是這么簡單!

多個 State Hooks

你可能會想,我的組件可定不會那么簡單,它的 state 遠比這里的 count 多得多,要怎么使用多個 state 并管理它們呢?

看看下面的代碼,你會發(fā)現(xiàn)原來事情那么簡單!

import React, { useState } from 'react';

function AllTheThings() {
  const [count, setCount] = useState(0);
  const [books, setBooks] = useState([{ name: 'Common Stock Uncommon Profit', author: 'Philip A. Fisher' }])
  const [coupon, setCoupon] = useState(null);

  return <div>{/_ use all those things here _/}></div>;
}

我只能說,一目了然,可以說是相當?shù)暮啙嵜髁肆恕?/p>

useEffect

除了 state,我們使用 class component 的原因其實還有一個——生命周期函數(shù)。

既然說了,Hooks 是讓你能夠不用 class component 就使用 React 特性的一種解決方案,那么對于組件生命周期的管理,Hooks 是怎么做到的呢?

Effects are similar to componentDidMount, componentDidUpdate, and componentWillUnmount.

前面的 useState 我們能理解,它能使用 state,那這邊的 useEffect 為啥叫這個名字呢?其實這些生命周期都是用來處理一些副作用的(side-effects),例如:

  • 獲取數(shù)據(jù)
  • 手動操作 DOM
  • 訂閱一個流(RxJS)

所以我們把它稱作 useEffect,意思是用來管理這些副作用的地方。

好的,說了那么多,讓我們來看看具體怎么使用它吧~

componentDidMount

一般在這個生命周期里,我們會做一些請求數(shù)據(jù)、操作DOM或者訂閱流的操作,對應(yīng)的使用 useEffect 的方法也很簡單,

function DoSomethingCrazy() {
  useEffect(() => {
    console.log('great expectation');
    document.title = 'What a long, strange trip it\'s been'
  })
}

只需要給 useState 傳遞一個想要在此時執(zhí)行的函數(shù)就可以了。

componentDidUpdate

這也是一個經(jīng)常使用的生命周期,通常會需要在在 state 發(fā)生改變的時候,做一些副作用的操作,我們可以這么寫:

// only run if count changes
useEffect(
  () => {
    // run here if count changes
  },
  [count]
);

componentWillUnmount

在即將 unmount 的時候,我們通常需要對之前訂閱的流進行解除:

useEffect(() => {
  UserAPI.subscribeToUserLikes();

  // unsubscribe
  return () => {
    UserAPI.unsubscribeFromUserLikes();
  }
});

你看,多么簡單!

讓我們把 useState 和 useEffect 整合起來

我們創(chuàng)建一個 GithubUsers.js 的組件,我們需要通過 API 獲取 github 的一些隨機的用戶,并把他們展示在頁面上。過去,我們需要使用類組件去做這些事情,現(xiàn)在直接使用函數(shù)組件就能完全搞定啦!

import React, { useState } from 'react';

export function GithubUsers() {
  const [users, setUsers] = useState([]);

  useEffect(() => {
    fetch('https://api.github.com/users')
      .then(response => response.json())
      .then(data => {
        setUsers(data);
      });
  }, []);  // 這里是個空數(shù)組,因為我們不需要每次更新的時候都做這個操作

  return (
    <div className="section">
      {users.map(user => (
        <div key={user.id} className="card">
          <h5>{user.login}</h5>
        </div>
      ))}
    </div>
  );
}

好啦,快去和小伙伴炫耀你已經(jīng)學(xué)會 React Hooks 了吧!??

小結(jié)

React 的 state hooks 和 effect hooks 可以說是非常棒的新特性了,它不僅讓我們知道 React 的團隊始終沒有停下前進的腳步,而且這些新的特性也會讓新加入 React 的同學(xué)上手起來更加簡單和輕松~

所以現(xiàn)在,不要再問我這個組件是寫成 stateless functional component 還是 stateful class component 了,好嗎?

?著作權(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)容

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