react hooks

哈哈哈?,借用某某某的话。。。

  1. 你还在为该使用无状态组件(Function)还是有状态组件(Class)而烦恼吗
    ——拥有了hooks,你再也不需要写Class了,你的所有组件都将是Function。
  2. 你还在为搞不清使用哪个生命周期钩子函数而日夜难眠吗?
    ——拥有了Hooks,生命周期钩子函数可以先丢一边了。
  3. 你在还在为组件中的this指向而晕头转向吗?
    ——既然Class都丢掉了,哪里还有this?你的人生第一次不再需要面对this
    这样说来,你是不是就会对他很感兴趣。
首先来一个最简单的例子
  • 简单的有状态组件
import React from 'react';

class Index 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>
        );
    }
}
export default Index
  • hooks实现的组件
import React,{ useState } from 'react';

function Index() {
    const [count, setCount] = useState(0); // 1.
    return (
        <div>
            <p>You clicked {count} times</p>  //2.
            <button onClick={() => setCount(count + 1)}>  //3.
                Click me
            </button>
        </div>
    );
}

export default Index;

从行数上来说,是不是少了一些。可以看到Index变成了一个函数,但这个函数却又自己的状态(count),同时他嗨可以更新自己的状态(setCount),之所以这么厉害,是因为它注入了一个hook–useState,就是hook让我们的函数变成一个有状态的函数。
除此之外还有其他特性,我们一起来了解吧。

什么是State Hooks?

我们来看看上面的简单例子,可以从三个步骤开看

  1. 申明一个状态变量
const [count, setCount] = useState(0); //运用的是数组结构

useState是react自带的一个hook函数,它的作用就是用来申明变量。useState这个函数接受的参数使我们状态的初始值。他返回的是一个数组,第[0]项是当前的状态值,第[1]项是改变当前状态的函数方法。总结来说,就是useState申明了一个状态变量count,把他的初始值设置为0,同时还提供了一个更好count的函数setCount。

  1. 读取状态
 <p>You clicked {count} times</p>

这个就很简单,因为count就只是一个单纯的变量而已,就不需要写成{this.state.count}这种方式了
3. 更新状态

 <button onClick={() => setCount(count + 1)}>
    Click me
 </button>

当我们点击按钮的时候,会调用setCount这个方法,这个方法修改过的参数是修改过的新状态值。接下就交给react了,他会帮我们重新渲染Index这个组件,并且使用的是更新后的新状态。接下来的一个思考,为什么他能记住之前的状态呢。。。

Effect Hooks?

我们先对上面的例子进行改造
类组件写法:

import React from 'react';
class Index extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            count: 0
        };
    }
    componentDidMount() {
        document.title = `You clicked ${this.state.count} times`;
    }
    render() {
        return (
            <div>
                <Home/>
                <p>You clicked {this.state.count} times</p>
                <button onClick={() => this.setState({ count: this.state.count + 1 })}>
                    Click me
                </button>
            </div>
        );
    }
}
export default Index

hooks写法:

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

function Index() {
    const [count, setCount] = useState(0);
    useEffect(() => {
        // 更新文档的标题
        document.title = `点击${count}次`;
    })
    return (
        <div>
            <p>You clicked {count} times</p>
            <button onClick={() => setCount(count + 1)}>
                Click me
            </button>
        </div>
    );
}
export default Index;

我们写的有状态的组件,通常会产生很多副作用,比如发起ajax请求获取数据,添加一些监听的注册和取消注册,手动修改dom等等。我们之前都把这些副作用的函数写在生命周期函数钩子里,比如componentDidMount,componentDidUpdate和componentWillUnmount。而现在的useEffect就相当与这些声明周期函数钩子的集合体。它以一抵三。
这里要注意几点:
第一,react首次渲染和之后的每次渲染都会调用一遍传给useEffect的函数。而之前我们要用两个声明周期函数来分别表示首次渲染(componentDidMount),和之后的更新导致的重新渲染(componentDidUpdate)。

第二,useEffect中定义的副作用函数的执行不会阻碍浏览器更新视图,也就是说这些函数是异步执行的,而之前的componentDidMount或componentDidUpdate中的代码则是同步执行的。这种安排对大多数副作用说都是合理的,但有的情况除外,比如我们有时候需要先根据DOM计算出某个元素的尺寸再重新渲染,这时候我们希望这次重新渲染是同步发生的,也就是说它会在浏览器真的去绘制这个页面前发生

  • 怎么跳过一些不必要的副作用函数
    每次重新渲染都要执行一遍这些副作用函数,显然是不经济的。怎么跳过一些不必要的计算呢?我们只需要给useEffect传第二个参数即可。用第二个参数来告诉react只有当这个参数的值发生改变时,才执行我们传的副作用函数(第一个参数)。
useEffect(() => {
  document.title = `You clicked ${count} times`;
}, [count]); // 只有当count的值发生变化时,才会重新执行`document.title`这一句
还有哪些自带的Effect Hooks?

useContext
useReducer
useCallback
useMemo
useRef
useImperativeMethods
useMutationEffect
useLayoutEffect

怎么写自定义的Effect Hooks?
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值