从Preact学习hooks原理--useState

什么是Preact

Preact可以理解为体积更小的react,实现了react的大部分功能,源码相对于react比较简单。Preact也实现了react中的hooks的内容,所以本文从Preact中探索hooks的实现原理。

useState的使用

先来看下useState的简单使用,在这里我们借用官网的例子。

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

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

可以看到,函数组件里面也有了state,也可以通过setCount来改变count的值。

useState的原理

1.useState

在Preact中useState的代码如下

export function useState(initialState) {
	return useReducer(invokeOrReturn, initialState);
}

useState接收一个参数initialState,返回了一个函数userReducer的返回值

2.userReducer
export function useReducer(reducer, initialState, init) {
	// 定义了hookState,调用getHookState
	const hookState = getHookState(currentIndex++);
	if (!hookState._component) {
		// 给hookState添加_component属性
		hookState._component = currentComponent;
		// 给hookState添加_value属性
		hookState._value = [
			// 对initialState做处理
			!init ? invokeOrReturn(undefined, initialState) : init(initialState),

			action => {
				// 执行reducer,返回nextValue
				const nextValue = reducer(hookState._value[0], action);
				if (hookState._value[0] !== nextValue) {
					// 如果hookState._value第一个参数等于nextValue,调用setState更新状态
					hookState._value[0] = nextValue;
					hookState._component.setState({});
				}
			}
		];
	}

	return hookState._value;
}

userReducer的代码比较复杂,下面我们一一说明:

  1. 接收3个参数reducerinitialStateinit
  2. 定义了hookState,调用getHookState
  3. hookState添加_value属性
  4. 处理hookState_value属性
  5. 返回了hookState._value

在这里我们回想下useState的用法,const [count, setCount] = useState(0);
useState可以接收一个初始值,返回一个count,这个count是根据初始值变化得来的,
另个一参数setCount,接收一个参数,产生的作用是改变了count的值,并改变视图。
正好对应了上面的第4步: 处理hookState_value属性
那么问题又来了,hookState又是什么?

根据上面的代码const hookState = getHookState(currentIndex++);,getHookState函数接收一个参数currentIndex++,返回值赋给hookState,废话不多说,上代码!

3.getHookState
import { options } from 'preact';

function getHookState(index) {
	// 瞅瞅Preact里面有没有_hook,从当前组件中拿到hook的state
	if (options._hook) options._hook(currentComponent);
	// 定义一个数组_list
	const hooks =
		currentComponent.__hooks ||
		(currentComponent.__hooks = { _list: [], _pendingEffects: [] });

	if (index >= hooks._list.length) {
		hooks._list.push({});
	}
	// 返回这个数组index这一项
	return hooks._list[index];
}

getHookState做的是:定义一个数组,根据传来的值,返回匹配到的数组。由此,我们会想到什么呢,对就是这个,一图胜千言!
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值