React Hooks已经推出一段时间,大家应该比较熟悉,或者多多少少在项目中用过。写这篇文章简单分析一下Hooks的原理,并带大家实现一个简易版的Hooks。
这篇写的比较细,相关的知识点都会解释,给大家刷新一下记忆。
Hooks
Hooks是React 16.8推出的新功能。以这种更简单的方式进行逻辑复用。之前函数组件被认为是无状态的。但是通过Hooks,函数组件也可以有状态,以及类组件的生命周期方法。
useState用法示例:
import React, {
useState } from 'react';
function Example() {
// count是组件的状态
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {
count} times</p>
<button onClick={
() => setCount(count + 1)}> Click me </button>
</div>
);
}
闭包
开始之前,我们来简单回顾一下闭包的概念,因为Hooks的实现是高度依赖闭包的。
闭包(Closure),Kyle Simpson在《你不知道的Javascript》中总结闭包是:
Closure is when a function is able to remember and access its lexical scope even when that function is executing outside its lexical scope.
闭包就是,函数可以访问到它所在的词法作用域,即使是在定义以外的位置调用。
闭包的一个重要应用就是,实现内部变量/私有数据。
var counter = 0;
// 给计数器加1
function add() {
counter += 1;
}
// 调用 add() 3次
add(); // 1
add(); // 2
counter = 1000;
add(); // 1003
这里因为counter不是内部变量,所以谁都能修改它的值。我们不想让人随意修改counter怎么办?这时候就可以用闭包:
function getAdd() {
var counter = 0;
return function add() {
counter += 1;}
}
var add = getAdd();
add(); // 1
add(); // 2
add(); // 3
counter = 1000 // error! 当前位置无法访问counter
我们还可以把函数的定义挪到调用的位置,用一个立即执行函数表达式IIFE(Immediately Invoked Function Expression):
var add = (function getAdd() {
var counter = 0;
return function add() {
counter += 1;}
})();
add(); // 1
add(); // 2
add(); // 3
这种通过IIFE创建闭包的方式也叫做模块模式(Module Pattern),它创建了一个封闭的作用域,只有通过返回的对象/方法来操纵作用域中的值。这个模式由来已久了,之前很多Javascript的库,比如jQuery,就是用它来导出自己的实例的。
开始动手实现
理清闭包的概念后可以着手写了。从简单的入手,先来实现setState。
function useState(initialValue) {
var _val = initialValue; // _val是useState的变量
function state() {
// state是一个内部函数,是闭包
return _val;
}
function setState(newVal)