react hooks将会是react未来的趋势。

开发环境搭建与示例编写

准备好,要开始咯!

开发环境搭建

React Hooks是React的新特性,不需要安装,只需要React版本在16.8以上,即可使用。

示例

首先编写一个小demo:

import React, { useState } from 'react';

export default function Example() {
    const [ count, setCount ] = useState(0);  // 数组解构

    return (
        <div>
            <div>你已经点击了{count}次</div>
            <button onClick={() => setCount(count + 1)}>点击</button>
        </div>
    )
}

注意:

useState是一个方法,接收一个初始值。返回结果是一个数组:数组第一项是this.state,第二项是this.setState,在上面的例子里,只是给它们去了一个别名。

多状态声明

编写多个useState语句即可。

import React, { useState } from 'react';

export default function Example() {
    const [name, setName] = useState('白山');
    const [age, setAge] = useState(18);

    return (
        <div>
            <div>{name}</div>
            <div>{age}</div>
        </div>
    )
}

注意:useState语句不能放在条件语句中。例如:

const isEmpty = true;
if (isEmpty) {
    const [name, setName] = useState('白山');
}

使用useEffect代替生命周期

在react中,有各式各样的生命周期函数来辅助整个程序的运行。这些生命周期函数在Hooks可以使用useEffect进行替代。

代替componentDidMountcomponentDidUpdate

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

export default function Example() {
    const [ count, setCount ] = useState(0);  // 数组解构

    useEffect(() => {
        console.log(`done: ${count}`);
    });

    return (
        <div>
            <div>你已经点击了{count}次</div>
            <button onClick={() => setCount(count + 1)}>点击</button>
        </div>
    )
}

注解:

useEffect是一个函数,它的第一个参数是一个匿名函数,useEffect触发时将会执行这个函数。
useEffect的存在相当于componentDidMount + componentDidUpdate,React首次渲染和之后的每次渲染都会调用一遍useEffect函数。
useEffect不会阻碍视图的更新,因为它是异步的。

因为useEffect是异步`的,所以它无法完成一些实时的操作。

比如,实时计算屏幕大小,调整页面布局,这个它是无法准确完成的,因为它异步的特性,会存在延时的情况。

🤗别着急,接着往下看👇👇👇

实现仅componentDidMount

上面的写法让它同时替代了两个生命周期函数,那如果我需要在首次渲染和重新渲染后执行不同的函数该怎么做呢?

首先,我们实现仅首次渲染后执行。这里需要介绍一下useEffect的第二个参数,它的第二个参数是一个数组。只有数组中的值发生变化了,才会调用 useEffect() ,而不是每次在渲染的时候调用。

当第二个参数为空数组([])的时候,代表不监听任何参数变化,即只有在组件初始化或销毁的时候才会触发,用来代替 componentDidMountcomponentWillUnmount

先来看一下如何实现componentDidMount

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

export default function Example() {
    const [count, setCount] = useState(0);  // 数组解构

    useEffect(() => {
        console.log('componentDidMount');
    }, []);

    return (
        <div>
            <div>你已经点击了{count}次</div>
            <button onClick={() => setCount(count + 1)}>点击</button>
        </div>
    )
}

对比一下,就会发现仅仅只有一处地方修改了,那就是在useEffect的第二个参数上加了一个空数组。

实现componentDidUpdate

例如我们监听一下变量count的更新:

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

export default function Example() {
    const [count, setCount] = useState(0);  // 数组解构

    useEffect(() => {
        console.log('componentDidMount');
    }, []);

    useEffect(() => {
        console.log(`componentDidUpdate: you click ${count} times`);
    }, [count]);

    return (
        <div>
            <div>你已经点击了{count}次</div>
            <button onClick={() => setCount(count + 1)}>点击</button>
        </div>
    )
}

以上代码在执行的时候,第二个useEffect()函数就相当于conponentDidUpdate,首次渲染和变量count更新时都会执行,因为首次渲染时,变量count也被定义并被赋予初始值。

实现componentWillUnmount

以上介绍了如何使用useEffect实现首次加载的副作用和数据更新的副作用,而在实际的开发中,我们可能还需要在组件卸载时做一些操作。

这一点React Hooks也帮我们想到了。🤓

我们只需要在 useEffect() 中返回一个函数,就可以模拟 componentWillUnmount 的功能。

为了模拟卸载的状态,这里需要引入React Router用于路由的切换。

npm install --save react-router-dom

示例如下:

import React, { useState, useEffect } from 'react';
import { BrowserRouter as Router, Route, Link } from "react-router-dom"

export default function Example() {
    const [count, setCount] = useState(0);  // 数组解构

    // useEffect(() => {
    //     console.log('componentDidMount');
    // }, []);

    // useEffect(() => {
    //     console.log(`componentDidUpdate: you click ${count} times`);
    // }, [count]);

    function Index() {
        useEffect(() => {
            console.log('老弟你来了 =》 index');
            return () => {
                // componentWillUnmount
                console.log('老弟你走了 => index');
            };
        }, []);
        return <h1>index</h1>;
    }

    function List() {
        useEffect(() => {
            console.log('老弟你来了 =》 list');
            return () => {
                // componentWillUnmount
                console.log('老弟你走了 => list');
            };
        }, []);
        return <h1>list</h1>;
    }

    return (
        <div>
            <div>你已经点击了{count}次</div>
            <button onClick={() => setCount(count + 1)}>点击</button>

            <Router>
                <ul>
                    <li> <Link to="/">首页</Link> </li>
                    <li><Link to="/list/">列表</Link> </li>
                </ul>
                <Route path="/" exact component={Index} />
                <Route path="/list/" component={List} />
            </Router>
        </div>
    )
}

至此,componentWillUnmount也就实现咯。

总结:

useEffect其实等同于类组件的 componentDidMountcomponentDidUpdatecomponentWillUnmount 的结合体 。