[React] Custom useState and useEffect hook
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)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2022-07-31 [Functional Programming] Make a flip and reverse functions
2021-07-31 [SAA + SAP] 13. S3
2020-07-31 [XState] History state
2020-07-31 [XState] Nested State
2018-07-31 [Angular] New in V6.1
2018-07-31 [Javascript] JavaScript赋值时的传值与传址
2017-07-31 [React Intl] Use Webpack to Conditionally Include an Intl Polyfill for Older Browsers