首页 > 其他分享 >[React] Custom useState and useEffect hook

[React] Custom useState and useEffect hook

时间:2024-07-31 14:39:55浏览次数:6  
标签:const render INITIALIZATION effect React hook useState useEffect id

import { flushSync } from 'react-dom'
import { createRoot } from 'react-dom/client'

let hookIndex = 0
const states: Array<[any, (newState: any) => void]> = []
const INITIALIZATION = Symbol('INITIALIZATION')
const UPDATE = Symbol('UPDATE')
type Phase = typeof INITIALIZATION | typeof UPDATE
let phase = INITIALIZATION

/**
 * 1. Multiple useState problem
 * a. We need to use `INITIALIZATION` and `UPDATE symbol to keep track of the phase
 * b. We need a Hook id to keep track of the current hook
 * 	- ID will be from 0 and onwards
 *  - ID will be reset to 0 for each render
 */
function useState<T>(initialState: T) {
	const id = hookIndex++
	if (phase === INITIALIZATION) {
		states[id] = [
			initialState,
			(newState: T) => {
				states[id][0] = newState
				render(UPDATE)
			},
		]
	}

	return states[id] as [T, (newState: T) => void]
}

type EffectCallback = () => void
const effects: Array<{
	callback: EffectCallback
	deps?: any[]
	prevDeps?: any[]
}> = []

function useEffect(callback: EffectCallback, deps?: any[]) {
	const id = hookIndex++
	const prevDeps = effects[id]?.deps
	effects[id] = { callback, deps, prevDeps }
}

function Counter() {
	const [count, setCount] = useState(0)
	const [enabled, setEnabled] = useState(true)

	const increment = () => setCount(count + 1)
	const toggle = () => setEnabled(!enabled)

	useEffect(() => {
		console.log('efftivec')
	}, [enabled])

	return (
		<div className="counter">
			<button onClick={increment}>{count}</button>
			<button onClick={toggle}>{enabled ? 'Disable' : 'Enable'}</button>
		</div>
	)
}

const rootEl = document.createElement('div')
document.body.append(rootEl)
const appRoot = createRoot(rootEl)

function render(newPhase: Phase) {
	hookIndex = 0
	phase = newPhase

	flushSync(() => {
		appRoot.render(<Counter />)
	})

	for (const effect of effects) {
		if (!effect) continue

		const hasDepsChanged = effect.deps
			? !effect.deps.every((dep, i) => Object.is(dep, effect.prevDeps?.[i]))
			: true

		if (hasDepsChanged) {
			effect.callback()
		}
	}
}

render(INITIALIZATION)

 

标签:const,render,INITIALIZATION,effect,React,hook,useState,useEffect,id
From: https://www.cnblogs.com/Answer1215/p/18334566

相关文章

  • [React] Force React to update it's DOM by using flushSync
    Refertohttps://react.dev/reference/react-dom/flushSync Forexample,thebrowseronbeforeprintAPIallowsyoutochangethepageimmediatelybeforetheprintdialogopens.Thisisusefulforapplyingcustomprintstylesthatallowthedocumenttodispl......
  • 在react中使用Particles
    stepone首先封装一个粒子效果组件,option各项配置在tsparticles/react有介绍。//ParticleBackground.jsimportReact,{useEffect,useState}from"react";import{loadSlim}from"@tsparticles/slim";importParticles,{initParticlesEngine}from"@......
  • [vue3] Vue3源码阅读笔记 reactivity - collectionHandlers
    源码位置:https://github.com/vuejs/core/blob/main/packages/reactivity/src/collectionHandlers.ts这个文件主要用于处理Set、Map、WeakSet、WeakMap类型的拦截。拦截是为了什么?为什么要处理这些方法?Vue3实现响应式的思路是使用ProxyAPI在getter中收集依赖,在setter触发更新......
  • [vue3] Vue3源码阅读笔记 reactivity - collectionHandlers
    源码位置:https://github.com/vuejs/core/blob/main/packages/reactivity/src/collectionHandlers.ts这个文件主要用于处理Set、Map、WeakSet、WeakMap类型的拦截。拦截是为了什么?为什么要处理这些方法?Vue3实现响应式的思路是使用ProxyAPI在getter中收集依赖,在setter触发更新......
  • 上传多个图像时 React 前端和 Flask 后端出现 CORS 策略错误
    实际上,我已经在reactJs中制作了前端,在pythonFlask中制作了后端(使用cnn模型进行一些预测)。当我按照我的请求发送5到6张图像时,它工作正常,但是当我发送10到15张图像和一些时间时令人筋疲力尽,然后它给出了类似的错误,尽管我在下面给出的代码中设置了Cors:192.168.151.24/:1Accesst......
  • Zabbix 5.0 LTS 配置企业微信(Webhook)自动发送告警信息
    依据前面文章《Zabbix5.0LTSURL健康监测》环境,实现企业微信(Webhook)自动发送告警信息。一、创建企业微信机器人先在自己的企业微信群里创建一个机器人,并获取其WebHook地址。右击群聊天卡片,添加群机器人。获得一个类似下图的WebHook地址。注意,这个WebHook地址非常......
  • 快速开启react+electron应用,搭建启动问题
    注意:React本地启动在3000端口Electron在创建BrowserWindow的时候,可以读取本地的文件或者是url开发环境读取localhost:3000生产环境需要加载本地成型以后的本地文件,打包的时候再考虑一react脚手架create-react-app快速搭建reactnpxcreate-react-appmy-ap......
  • Python装饰器实现Hook类
    背景最近有个新的需求是使用Redmine进行一些提交前后的处理,备忘下一些思路实现思路为了统一代码的路径以及调用方式,封装了一个Hook类,按理来说是可以对所有类似的代码使用的,这里使用了Python装饰器,统一对同一个命名类的进行处理,相当于定义了函数的路由核心代码见下:Hook.pyfro......
  • React 的 KeepAlive 实战指南:深度解析组件缓存机制
    Vue的Keep-Alive组件是用于缓存组件的高阶组件,可以有效地提高应用性能。它能够使组件在切换时仍能保留原有的状态信息,并且有专门的生命周期方便去做额外的处理。该组件在很多场景非常有用,比如:·tabs缓存页面·分步表单·路由缓存在Vue中,通过KeepAlive包裹内的组件......
  • React实现过渡效果更新时间展示
     创建一个组件,实时展示时分秒,并且动态更新数据。数据变化时利用过渡效果动态更新。利用两个元素,重叠在一个位置,以达到交替变化的效果//创建秒显示节点<divclassName="textsecond"> <CSSTransition in="{renderSecond}" timeout="{1000}" classNames="fade" unmo......