浅谈React Hooks的原理及实现

什么是hooks?

在function组件中,每一次更新都是一次新的函数执行,为了保存一些状态,执行一些副作用钩子,所以产生了hooks,去帮助记录组件的状态,处理一些额外的副作用。

hooks的内部运行机制

首先每次执行一个hooks函数,都产生一个hook对象,里面保存了当前hook信息,然后将每个hooks按照定义的顺序以链表形式串联起来,并存放到memoizedState中。更新的时候,再按照顺序,从 memoizedState 中把上次记录的值拿出来。
这样我们就可以解答几个问题:
        Q:为什么只能在函数最外层调用 Hook?为什么不要在循环、条件判断或者子函数中调用。
        A:memoizedState 数组是按 hook定义的顺序来放置数据的,如果 hook 顺序变化,memoizedState 并不会感知到。
        Q:自定义的 Hook 是如何影响使用它的函数组件的?
        A:共享同一个 memoizedState,共享同一个顺序

useState原理

相信大家对useState都有一定的了解(react中Hooks的基本用法),在这里只补充一点。
setState 的两种用法:

         setState(value)
        setState(prevCount => ++prevCount)
当我们更新state需要依赖之前的值时,我们可以在setState中接受一个函数来实现。
接下来我们简单地实现一个useState。

import { Button } from 'antd';

let state: any; // 把 state 存储在外面

const useState = (initialValue: any) => {
// 如果没有 state,说明是第一次执行,把 initialValue 复制给它
    state = state | initialValue; 
    const setState = (newState: any) => {
        state = newState;
    }
    return [state, setState];
}

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

    return (
        <div>
            <div>{count}</div>
            <Button
                onClick={() => {
                    setCount(count + 1);
                }}
            >
                点击
            </Button>
        </div>
    );
}

useEffect

我们知道 useEffect 有几个特点:
• 有两个参数 callback 和 dependencies 数组
• 如果 dependencies 不存在,那么 callback 每次 render 都会执行
• 如果 dependencies 存在,只有当它发生了变化, callback 才会执行
我们再简单的实现一个useEffect:

// _deps 记录 useEffect 上一次的 依赖
let _deps: { [x: string]: any; };

function useEffect(callback: () => void, depArray: any[]) {
    // 如果 dependencies 不存在
    const hasNoDeps = !depArray;

    // depArray未改变则为false
    const hasChangedDeps = _deps
    ? !depArray.every((el, i) => el === _deps[i]) // 两次的 dependencies 是否完全相等
    : true;

    // 如果 dependencies 不存在,或者 dependencies 有变化
    if (hasNoDeps || hasChangedDeps) {
        callback();
        _deps = depArray;
    }
}

到这里我们又可以解决一个问题:
Q:为什么第二个参数是空数组,相当于 componentDidMount ?
A:因为依赖一直不变化,callback 不会二次执行。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值