手写Hooks核心原理
手写实现useState useEffect useReducer
一. useState 钩子函数的实现原理
// import { useState } from 'react'
import ReactDOM from 'react-dom'
let state = []
let setters = []
let stateIndex = 0function createSetter (index) {return function (newState) {state[index] = newStaterender()}
}function useState (initialState) {state[stateIndex] = state[stateIndex] ? state[stateIndex] : initialStatesetters.push(createSetter(stateIndex))let value = state[stateIndex]let setter = setters[stateIndex]stateIndex ++return [value, setter]
}function render () {stateIndex = 0ReactDOM.render(<App/>,document.getElementById('root'))
}export default function App () {const [count, setCount] = useState(0)const [name, setName] = useState('张三')return <div><span>{count}</span><button onClick={() => setCount(count + 1)}> + 1</button><span>{name}</span><button onClick={() => setName('李四')}> 李四</button></div>
}
二. useEffect 钩子函数的实现原理
// import { useState } from 'react'
import ReactDOM from 'react-dom'
let state = []
let setters = []
let stateIndex = 0function createSetter (index) {return function (newState) {state[index] = newStaterender()}
}function useState (initialState) {state[stateIndex] = state[stateIndex] ? state[stateIndex] : initialStatesetters.push(createSetter(stateIndex))let value = state[stateIndex]let setter = setters[stateIndex]stateIndex ++return [value, setter]
}function render () {stateIndex = 0effectIndex = 0ReactDOM.render(<App/>,document.getElementById('root'))
}// 上一次的依赖值
let prevDepsAry = []
let effectIndex = 0/*** useEffect* @param {function} callback 回调函数* @param {Array} depsAry 依赖数组* @returns {function} 清理函数*/
function useEffect (callback, depsAry) {if (Object.prototype.toString.call(callback) !== '[object Function]') throw new Error('useEffect 第一个参数必须是一个函数')if (typeof depsAry === 'undefined') {// 没有传递callback()} else {// 判断 depsAry 是不是数组if (Object.prototype.toString.call(depsAry) !== '[object Array]') throw new Error('useEffect 第二个参数必须是一个数组')// 获取上一次的状态值let prevDeps = prevDepsAry[effectIndex]// 将当前的依赖值和上一次的依赖值作对比,如果有变化,调用 callbacklet hasChanged = prevDeps ? !depsAry.every((dep, index) => dep === prevDeps[index]) : true// 判断值是否有变化if (hasChanged) {callback()}// 同步依赖值prevDepsAry[effectIndex++] = depsAry}
}export default function App () {const [count, setCount] = useState(0)const [name, setName] = useState('张三')useEffect(() => {console.log('Hello')}, [count])useEffect(() => {console.log('World')}, [name])// 测试不传监听数据的情况useEffect(() => {console.log('xxx')}, [])return <div><span>{count}</span><button onClick={() => setCount(count + 1)}> + 1</button><span>{name}</span><button onClick={() => setName('李四')}> 李四</button></div>
}
三.useReducer 钩子函数的实现原理
// import { useState } from 'react'
// import { useReducer } from 'react'
import ReactDOM from 'react-dom'
let state = []
let setters = []
let stateIndex = 0function createSetter (index) {return function (newState) {state[index] = newStaterender()}
}function useState (initialState) {state[stateIndex] = state[stateIndex] ? state[stateIndex] : initialStatesetters.push(createSetter(stateIndex))let value = state[stateIndex]let setter = setters[stateIndex]stateIndex ++return [value, setter]
}function render () {stateIndex = 0effectIndex = 0ReactDOM.render(<App/>,document.getElementById('root'))
}// 上一次的依赖值
let prevDepsAry = []
let effectIndex = 0/*** useEffect* @param {function} callback 回调函数* @param {Array} depsAry 依赖数组* @returns {function} 清理函数*/
function useEffect (callback, depsAry) {if (Object.prototype.toString.call(callback) !== '[object Function]') throw new Error('useEffect 第一个参数必须是一个函数')if (typeof depsAry === 'undefined') {// 没有传递callback()} else {// 判断 depsAry 是不是数组if (Object.prototype.toString.call(depsAry) !== '[object Array]') throw new Error('useEffect 第二个参数必须是一个数组')// 获取上一次的状态值let prevDeps = prevDepsAry[effectIndex]// 将当前的依赖值和上一次的依赖值作对比,如果有变化,调用 callbacklet hasChanged = prevDeps ? !depsAry.every((dep, index) => dep === prevDeps[index]) : true// 判断值是否有变化if (hasChanged) {callback()}// 同步依赖值prevDepsAry[effectIndex++] = depsAry}
}function useReducer (reducer, initialState) {const [state, setState] = useState(initialState)function dispatch (action) {const newState = reducer(state, action)setState(newState)}return [state, dispatch]
}export default function App () {function reducer(state, action) {switch (action.type) {case 'increment':return state + 1case 'decrement':return state - 1default:return state}}const [cnt, dispatch] = useReducer(reducer, 0)return <div><div><button onClick={() => dispatch({type: 'increment'})}> + 1</button><span>{cnt}</span><button onClick={() => dispatch({type: 'decrement'})}> - 1</button></div></div>
}
手写Hooks核心原理相关推荐
- babel原理_手写webpack核心原理,再也不怕面试官问我webpack原理
手写webpack核心原理 一.核心打包原理 1.1 打包的主要流程如下 1.2 具体细节 二.基本准备工作 三.获取模块内容 四.分析模块 五.收集依赖 六.ES6转成ES5(AST) 七.递归获取 ...
- 手写Vuex核心原理,再也不怕面试官问我Vuex原理
手写Vuex核心原理 文章目录 手写Vuex核心原理 一.核心原理 二.基本准备工作 三.剖析Vuex本质 四.分析Vue.use 五.完善install方法 六.实现Vuex的state 七.实现g ...
- 手写Redux核心原理
手写Redux核心原理 一.createStore核心逻辑实现 createStore的三个参数 reducer:根据actions类型对store中数据状态进行更改,返回一个新的状态 preload ...
- 定时器和promise_手写Promise核心原理,再也不怕面试官问我Promise原理
整体流程的介绍 整体流程的介绍 1. 定义整体结构 2. 实现Promise构造函数 3. 实现then方法 3.实现catch方法 4. 实现Promise.resolve 5.实现Promise. ...
- 05. 手写Spring核心框架
目录 05 手写Spring核心框架 Pt1 手写IoC/DI Pt1.1 流程设计 Pt1.2 基础配置 application.properties pom.xml web.xml Pt1.3 注 ...
- React Hooks核心原理与实战
React Hooks核心原理与实战 一.Hooks的优点 1.1 Hooks的含义 1.2 优点 二.常用的Hooks 2.1 useState 2.2 useEffect 2.3 useCallb ...
- 一起手写Vue3核心模块源码,掌握阅读源码的正确方法
最近和一个猎头聊天,说到现在前端供需脱节的境况.一方面用人方招不到想要的中高级前端,另一方面市场上有大量初级前端薪资要不上价. 特别是用 Vue 框架的,因为好上手,所以很多人将 Vue 作为入门框架 ...
- 【springboot】手写SpringBoot核心流程
通过手写模拟实现一个Spring Boot,就能以非常简单的方式就能知道Spring Boot大概是如何工作的. 工程与依赖 建一个工程,两个Module: spring-boot模块:表示sprin ...
- 手写识别底层原理_LinkedList底层原理和手写单链表
2.1 单链表技能点 · 认识单链表 o 特点 数据元素的存储对应的是不连续的存储空间,每个存储结点对应一个需要存储的数据元素. 每个结点是由数据域和指针域组成. 元素之间的逻辑关系通过存储节点之间的 ...
最新文章
- gridcontrol 控件的用法
- 利用计算机诊断ct故障,计算机在CT室工作中的应用及管理
- 机器学习-吴恩达-笔记-4-神经网络描述
- magento添加面包屑
- C语言经典例23-输出菱形图案
- 快速生成数据库文档--screw
- 腾讯程序员与医生相恋,却被女方父母拆散,你们不能在一起
- 从存活了1441年的企业,我们能学到什么?
- PHP+MYSQL【学生信息管理系统】(极简版)
- python_误差分析
- 华为云MVP周峥:气象预报是个技术活,大数据、超算、AI,缺一不可
- unity3d 地面印花_Unity3D 中的贴花效果 – 苍白的茧
- 前端小程序,h5,浏览器,app, doc,.docx,.ofd,.PDF,.WPS以及Office文档的在线解析预览方式
- 论文翻译:LP-3DCNN: Unveiling Local Phase in 3D Convolutional Neural Networks
- 设计模式 - 创建型模式_工厂方法模式
- 下载FATSQ,读取10条序列并计算每条序列的长度和GC含量
- 数学 计算机 生物学,数据:中国高校数学、物理、化学、生物、计算机5大学科实力排名!...
- case when的判断顺序_case when
- Filecoin节点部署
- 我的世界java转模组基岩,《我的世界》无模组激光门!瞬间就能粉碎基岩,凋灵也要被秒杀?...