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

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ù)組中的兩個變量是:
- 第一個變量是「狀態(tài)值」,它有點像
this.state - 第二個變量是一個更新「狀態(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, andcomponentWillUnmount.
前面的 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 了,好嗎?