React Hook 使用入门 React Hook 使用入门

什么是 Hook?

Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。Hook不能在 class 组件中使用。

State Hook 以及 Effect Hook

State Hook

import React, { useState, useEffect } from 'react';

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

    return (
        <div>
            <p>You clicked {count} times</p>
            <button onClick={() => setCount(count + 1)}>
                Click me
          </button>
        </div>
    );
}

以上代码等价于下面的 class 组件

class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            count: 0
        };
    }

    render() {
        return (
            <div>
                <p>You clicked {this.state.count} times</p>
                <button onClick={() => this.setState({ count: this.state.count + 1 })}>
                    Click me
            </button>
            </div>
        );
    }
}

更多内容查看官方文档

Effect Hook

使用 useEffect 给函数组件增加操作副作用的能力。它与 class 组件中的 componentDidMount、componentDidUpdate 和 componentWillUnmount 具有相同的用途,只不过被合并成了一个 API。

import React, { useState, useEffect } from 'react';
function Example() {
    const [count, setCount] = useState(0);
    // 相当于 componentDidMount 和 componentDidUpdate:
    useEffect(() => {
        // 使用浏览器的 API 更新页面标题
        document.title = `You clicked ${count} times`;

        return ()=>{
            console.log('update');
        }
    });
    return (
        <div>
        <p>You clicked {count} times</p>
        <button onClick={() => setCount(count + 1)}>
            Click me
        </button>
        </div>
    );
}
  • 在调用 useEffect 时,就是在告诉 React 在完成对 DOM 的更新后运行你的“副作用”函数。由于副作用函数是在组件内声明的,所以它可以访问组件内的 props 和 state。
  • 默认情况下,React 会在每次渲染后调用副作用函数(包括第一次渲染时)。
  • 副作用函数还可以通过返回一个函数来指定如何清除副作用。React 会在组件销毁或者后续渲染时重新执行副作用函数。

Hook 使用规则

  1. 只能在函数最外层调用 Hook,不要在循环、条件判断或子函数中调用。
  2. 只能在 React 的函数组件中调用 Hook,不要在其他 JavaScript 函数中调用(自定义 Hook 中可以调用)。

自定义 Hook

在组件之间重用一些状态逻辑,目前的两种主流方案是使用高级组件和 render props。现在可以使用自定义 Hook 达到同样的目的。

定义 Hook

自定义 Hook 是一个函数,其名称以 “use” 开头,函数内部可以调用其他的 Hook。如:

import React, { useState, useEffect } from 'react';

function useFriendStatus(friendID) {
    const [isOnline, setIsOnline] = useState(null);

    useEffect(() => {
        function handleStatusChange(status) {
        setIsOnline(status.isOnline);
        }

        ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange);
        return () => {
            ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange);
        };
    });

    return isOnline;
}

使用自定义 Hook

直接调用 const isOnline = useFriendStatus(props.friend.id); 就可以使用这个 Hook了。
自定义 Hook 是一种自然遵循 Hook 设计的约定,而并不是 React 的特性。

注意

  1. 自定义 Hook 必须以 “use” 开头。不遵循的话,由于无法判断某个函数是否包含对其内部 Hook 的调用,React 将无法自动检查你的 Hook 是否违反了 Hook 的规则
  2. 在两个组件中使用相同的 Hook 不会共享 state。自定义 Hook 是一种重用状态逻辑的机制(例如设置为订阅并存储当前值),所以每次使用自定义 Hook 时,其中的所有 state 和副作用都是完全隔离的。

更多参考自定义 Hook

参考:

  1. React 中文文档
  2. Hook API 索引