React Hooks 不完全指南

人生真正的本质不是希望,而是意义。人总是会死的,希望总是会破灭。但,只要你认为你人生的每一天都是有意义的,你才能够去面对你经历的所有苦难。

React Hooks 不完全指南_第1张图片
Photo by Ngọc Thuận on Unsplash

React 前段时间发布了 Hooks 这个新的特性,虽然还只是个提案,但是很多人都表示很看好它,今天我们就来了解一下 React Hooks。

准备工作

我们先使用 create-react-app 新建一个项目:

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

由于 React Hooks 还只是个 RFC 草案,所以我们还不能在正式版本中使用它,需要安装对应的 alpha 版本才可以:

$ cd  hooks
$ npm install -S [email protected] [email protected]
$ npm run start

一个简单的例子

我们可以打开项目,在 /src 下新建一个 Counter.js 文件:

import React, { useState } from 'react';

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

  return (
    

{count}

) }

怎么样?是不是看出了点什么?让我们把这个组件放到 App.js 下看看效果~

import { Counter } from './Counter'; 

class App extends Component {
  render() {
    return (
      
) } }

好吧,这其实就是个最简单的计数器组件,并没有什么了不起的。如果是在原来,我们会怎么写呢?

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 (
      

{this.state.count}

) } }

为了使用 state 我们必须使用 class component,所以你肯定已经明白了——什么是 React Hooks?

Hooks let you use React features without writing a class!

哦!这个叫做「钩子」的东西让我们再也不用写 class component 啦!

PS:也别担心,React 官方并没有不鼓励使用类组件的意思,只是给我们多提供了一种写组件的方式~

useState

好了,知道了 Hooks 是什么,让我们再回过头看看之前例子的代码吧!你一定对这个 useState 感到很好奇,它是怎么做到让 functional component 做到和 class component 一样的事情的呢?

我们其实可以看到,在 useState 方法前面,我们使用了数组解构的语法,其实 useState 也就给了我们两个变量,我们其实可以随便给它们命名,这个数组中的两个变量是:

  1. 第一个变量是「状态值」,它有点像 this.state
  2. 第二个变量是一个更新「状态值」的方法,有点像 this.setState

然后,我们传递给 useState 方法的其实是我们想要的「初始状态值」,在这里我们传了一个 0 作为 count 的初始值,相当于在构造函数中 this.state = { count: 0 } 的作用。

就是这么简单!

多个 State Hooks

你可能会想,我的组件可定不会那么简单,它的 state 远比这里的 count 多得多,要怎么使用多个 state 并管理它们呢?

看看下面的代码,你会发现原来事情那么简单!

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 
{/_ use all those things here _/}>
; }

我只能说,一目了然,可以说是相当的简洁明了了~

useEffect

除了 state,我们使用 class component 的原因其实还有一个——生命周期函数。

既然说了,Hooks 是让你能够不用 class component 就使用 React 特性的一种解决方案,那么对于组件生命周期的管理,Hooks 是怎么做到的呢?

Effects are similar to componentDidMount, componentDidUpdate, and componentWillUnmount.

前面的 useState 我们能理解,它能使用 state,那这边的 useEffect 为啥叫这个名字呢?其实这些生命周期都是用来处理一些副作用的(side-effects),例如:

  • 获取数据
  • 手动操作 DOM
  • 订阅一个流(RxJS)

所以我们把它称作 useEffect,意思是用来管理这些副作用的地方。

好的,说了那么多,让我们来看看具体怎么使用它吧~

componentDidMount

一般在这个生命周期里,我们会做一些请求数据、操作DOM或者订阅流的操作,对应的使用 useEffect 的方法也很简单,

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

只需要给 useState 传递一个想要在此时执行的函数就可以了。

componentDidUpdate

这也是一个经常使用的生命周期,通常会需要在在 state 发生改变的时候,做一些副作用的操作,我们可以这么写:

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

componentWillUnmount

在即将 unmount 的时候,我们通常需要对之前订阅的流进行解除:

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

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

你看,多么简单!

让我们把 useState 和 useEffect 整合起来

我们创建一个 GithubUsers.js 的组件,我们需要通过 API 获取 github 的一些随机的用户,并把他们展示在页面上。过去,我们需要使用类组件去做这些事情,现在直接使用函数组件就能完全搞定啦!

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);
      });
  }, []);  // 这里是个空数组,因为我们不需要每次更新的时候都做这个操作

  return (
    
{users.map(user => (
{user.login}
))}
); }

好啦,快去和小伙伴炫耀你已经学会 React Hooks 了吧!

小结

React 的 state hooks 和 effect hooks 可以说是非常棒的新特性了,它不仅让我们知道 React 的团队始终没有停下前进的脚步,而且这些新的特性也会让新加入 React 的同学上手起来更加简单和轻松~

所以现在,不要再问我这个组件是写成 stateless functional component 还是 stateful class component 了,好吗?

你可能感兴趣的:(React Hooks 不完全指南)