React-Hooks源码深度解读

本文详细解析了React Hooks中的useState和useEffect,包括它们的使用、模拟实现及注意事项。深入探讨了hooks的规则,解释了不能在循环、条件或嵌套函数中使用的原因。并通过源码解析揭示了useState实际上是如何工作的,同时对比了preact中的hooks实现。文章旨在帮助开发者更好地理解和应用React Hooks,避免常见问题,提高开发效率。
摘要由CSDN通过智能技术生成

useState 解析

useState 使用

通常我们这样来使用 useState 方法,

function App() {const [num, setNum] = useState(0);const add = () => {setNum(num + 1);};return (<div><p>数字: {num}</p><button onClick={add}> +1 </button></div>);
} 

useState 的使用过程,我们先模拟一个大概的函数

function useState(initialValue) {var value = initialValuefunction setState(newVal) {value = newVal}return [value, setState]
} 

这个代码有一个问题,在执行 useState 的时候每次都会 var _val = initialValue,初始化数据;

于是我们可以用闭包的形式来保存状态。

const MyReact = (function() { // 定义一个 value 保存在该模块的全局中let valuereturn {useState(initialValue) {value = value || initialValue function setState(newVal) {value = newVal}return [value, setState]}}
})() 

这样在每次执行的时候,就能够通过闭包的形式 来保存 value。

不过这个还是不符合 react 中的 useState。因为在实际操作中会出现多次调用,如下。

function App() {const [name, setName] = useState('Kevin');const [age, setAge] = useState(0);const handleName = () => {setNum('Dom');};const handleAge = () => {setAge(age + 1);};return (<div><p>姓名: {name}</p><button onClick={handleName}> 改名字 </button> <p>年龄: {age}</p><button onClick={handleAge}> 加一岁 </button></div>);
} 

因此我们需要在改变 useState 储存状态的方式

useState 模拟实现

const MyReact = (function() {// 开辟一个储存 hooks 的空间let hooks = []; // 指针从 0 开始let currentHook = 0 return {// 伪代码 解释重新渲染的时候 会初始化 currentHookrender(Component) {const Comp = Component()Comp.render()currentHook = 0 // 重新渲染时候改变 hooks 指针return Comp},useState(initialValue) {hooks[currentHook] = hooks[currentHook] || initialValueconst setStateHookIndex = currentHook// 这里我们暂且默认 setState 方式第一个参数不传 函数,直接传状态const setState = newState => (hooks[setStateHookIndex] = newState)return [hooks[currentHook++], setState]}}
})() 

因此当重新渲染 App 的时候,再次执行 useState 的时候传入的参数 kevin , 0 也就不会去使用,而是直接拿之前 hooks 存储好的值。

hooks 规则

官网 hoos 规则中明确的提出 hooks 不要再循环,条件或嵌套函数中使用。

为什么不可以?

我们来看下

下面这样一段代码。执行 useState 重新渲染,和初始化渲染 顺序不一样就会出现如下问题

如果了解了上面 useState 模拟写法的存储方式,那么这个问题的原因就迎刃而解了。

相关参考视频讲解:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值