美文网首页
React Hooks 不完全指南

React Hooks 不完全指南

作者: 可乐前端 | 来源:发表于2018-12-06 00:53 被阅读0次

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

    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 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>
        )
      }
    }
    

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

    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,所以你肯定已经明白了——什么是 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 <div>{/_ use all those things here _/}></div>;
    }
    

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

    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 (
        <div className="section">
          {users.map(user => (
            <div key={user.id} className="card">
              <h5>{user.login}</h5>
            </div>
          ))}
        </div>
      );
    }
    

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

    小结

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

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

    相关文章

      网友评论

          本文标题:React Hooks 不完全指南

          本文链接:https://www.haomeiwen.com/subject/hqmgcqtx.html