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

React 前段時(shí)間發(fā)布了 Hooks 這個(gè)新的特性,雖然還只是個(gè)提案,但是很多人都表示很看好它,今天我們就來了解一下 React Hooks。
準(zhǔn)備工作
我們先使用 create-react-app 新建一個(gè)項(xiàng)目:
$ npm install -g npx
$ npx create-react-app hooks
由于 React Hooks 還只是個(gè) RFC 草案,所以我們還不能在正式版本中使用它,需要安裝對(duì)應(yīng)的 alpha 版本才可以:
$ cd hooks
$ npm install -S react@16.7.0-alpha.2 react-dom@16.7.0-alpha.2
$ npm run start
一個(gè)簡單的例子
我們可以打開項(xiàng)目,在 /src 下新建一個(gè) 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>
)
}
怎么樣?是不是看出了點(diǎn)什么?讓我們把這個(gè)組件放到 App.js 下看看效果~
import { Counter } from './Counter';
class App extends Component {
render() {
return (
<div className="App">
<Counter />
</div>
)
}
}
好吧,這其實(shí)就是個(gè)最簡單的計(jì)數(shù)器組件,并沒有什么了不起的。如果是在原來,我們會(huì)怎么寫呢?
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!
哦!這個(gè)叫做「鉤子」的東西讓我們?cè)僖膊挥脤?class component 啦!
PS:也別擔(dān)心,React 官方并沒有不鼓勵(lì)使用類組件的意思,只是給我們多提供了一種寫組件的方式~
useState
好了,知道了 Hooks 是什么,讓我們?cè)倩剡^頭看看之前例子的代碼吧!你一定對(duì)這個(gè) useState 感到很好奇,它是怎么做到讓 functional component 做到和 class component 一樣的事情的呢?
我們其實(shí)可以看到,在 useState 方法前面,我們使用了數(shù)組解構(gòu)的語法,其實(shí) useState 也就給了我們兩個(gè)變量,我們其實(shí)可以隨便給它們命名,這個(gè)數(shù)組中的兩個(gè)變量是:
- 第一個(gè)變量是「狀態(tài)值」,它有點(diǎn)像
this.state - 第二個(gè)變量是一個(gè)更新「狀態(tài)值」的方法,有點(diǎn)像
this.setState
然后,我們傳遞給 useState 方法的其實(shí)是我們想要的「初始狀態(tài)值」,在這里我們傳了一個(gè) 0 作為 count 的初始值,相當(dāng)于在構(gòu)造函數(shù)中 this.state = { count: 0 } 的作用。
就是這么簡單!
多個(gè) State Hooks
你可能會(huì)想,我的組件可定不會(huì)那么簡單,它的 state 遠(yuǎn)比這里的 count 多得多,要怎么使用多個(gè) state 并管理它們呢?
看看下面的代碼,你會(huì)發(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>;
}
我只能說,一目了然,可以說是相當(dāng)?shù)暮啙嵜髁肆恕?/p>
useEffect
除了 state,我們使用 class component 的原因其實(shí)還有一個(gè)——生命周期函數(shù)。
既然說了,Hooks 是讓你能夠不用 class component 就使用 React 特性的一種解決方案,那么對(duì)于組件生命周期的管理,Hooks 是怎么做到的呢?
Effects are similar to
componentDidMount,componentDidUpdate, andcomponentWillUnmount.
前面的 useState 我們能理解,它能使用 state,那這邊的 useEffect 為啥叫這個(gè)名字呢?其實(shí)這些生命周期都是用來處理一些副作用的(side-effects),例如:
- 獲取數(shù)據(jù)
- 手動(dòng)操作 DOM
- 訂閱一個(gè)流(RxJS)
所以我們把它稱作 useEffect,意思是用來管理這些副作用的地方。
好的,說了那么多,讓我們來看看具體怎么使用它吧~
componentDidMount
一般在這個(gè)生命周期里,我們會(huì)做一些請(qǐng)求數(shù)據(jù)、操作DOM或者訂閱流的操作,對(duì)應(yīng)的使用 useEffect 的方法也很簡單,
function DoSomethingCrazy() {
useEffect(() => {
console.log('great expectation');
document.title = 'What a long, strange trip it\'s been'
})
}
只需要給 useState 傳遞一個(gè)想要在此時(shí)執(zhí)行的函數(shù)就可以了。
componentDidUpdate
這也是一個(gè)經(jīng)常使用的生命周期,通常會(huì)需要在在 state 發(fā)生改變的時(shí)候,做一些副作用的操作,我們可以這么寫:
// only run if count changes
useEffect(
() => {
// run here if count changes
},
[count]
);
componentWillUnmount
在即將 unmount 的時(shí)候,我們通常需要對(duì)之前訂閱的流進(jìn)行解除:
useEffect(() => {
UserAPI.subscribeToUserLikes();
// unsubscribe
return () => {
UserAPI.unsubscribeFromUserLikes();
}
});
你看,多么簡單!
讓我們把 useState 和 useEffect 整合起來
我們創(chuàng)建一個(gè) GithubUsers.js 的組件,我們需要通過 API 獲取 github 的一些隨機(jī)的用戶,并把他們展示在頁面上。過去,我們需要使用類組件去做這些事情,現(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);
});
}, []); // 這里是個(gè)空數(shù)組,因?yàn)槲覀儾恍枰看胃碌臅r(shí)候都做這個(gè)操作
return (
<div className="section">
{users.map(user => (
<div key={user.id} className="card">
<h5>{user.login}</h5>
</div>
))}
</div>
);
}
好啦,快去和小伙伴炫耀你已經(jīng)學(xué)會(huì) React Hooks 了吧!??
小結(jié)
React 的 state hooks 和 effect hooks 可以說是非常棒的新特性了,它不僅讓我們知道 React 的團(tuán)隊(duì)始終沒有停下前進(jìn)的腳步,而且這些新的特性也會(huì)讓新加入 React 的同學(xué)上手起來更加簡單和輕松~
所以現(xiàn)在,不要再問我這個(gè)組件是寫成 stateless functional component 還是 stateful class component 了,好嗎?