useState
useMemo
useReducer
useState
const lastStates = []
let index = 0
function useState(initialState) {
lastStates[index] = lastStates[index] || initialState
const currentIndex = index
function setState(nextState) {
lastStates[currentIndex] = nextState
// render()
}
return [lastStates[index++], setState]
}
useCallback
import { isChanged } from './utils'
let lastCallback
let lastDependencies
function useCallback(callback, dependencies) {
if (lastDependencies) {
if (isChanged(lastDependencies, dependencies)) { // 依赖项改变了, 返回新的callback
lastCallback = callback
lastDependencies = dependencies
}
} else { // 没有依赖项, 每次返回新的callback
lastCallback = callback
lastDependencies = dependencies
}
return lastCallback
}
// export function isChanged(lastDeps, deps) {
// const changed = !lastDeps.every((dep, idx) => {
// return dep === deps[idx]
// })
// return changed
// }
useMemo
import { isChanged } from './utils'
let lastMemo
let lastDependencies
function useMemo(callback, dependencies) {
if (lastDependencies) {
if (isChanged(lastDependencies, dependencies)) {
lastMemo = callback()
lastDependencies = dependencies
}
} else {
lastMemo = callback()
lastDependencies = dependencies
}
}
useReducer
let lastState
function useReducer(reducer, initialState) {
lastState = lastState || initialState
const dispatch = (action) => {
lastState = reducer(lastState, action)
// render()
}
return [lastState, dispatch]
}
// useage
const reducer = (state, action) => {
switch(action.type) {
case 'add':
return state + 1
default:
return state
}
}
cosnt [state, dispatch] = useReducer(reducer, 0)
useContext
function useContext(context) {
return context._currentValue
}
useEffect
import { isChanged } from './utils'
let lastDependencies
// callback在浏览器渲染完成之后执行
function useEffect(callback, dependencies) {
if (lastDependencies) {
if (isChanged(lastDependencies, dependencies)) { // 依赖项改变了, 返回新的callback
setTimeout(callback, 0)
lastDependencies = dependencies
}
} else { // 没有依赖项, 每次返回新的callback
setTimeout(callback, 0)
lastDependencies = dependencies
}
return lastCallback
}
useLayoutEffect
import { isChanged } from './utils'
let lastDependencies
// callback在render之后,浏览器渲染之前执行
function useLayoutEffect(callback, dependencies) {
if (lastDependencies) {
if (isChanged(lastDependencies, dependencies)) { // 依赖项改变了, 返回新的callback
Promise.resolve().then(callback)
// 或者
// queueMicrotask(callback)
lastDependencies = dependencies
}
} else { // 没有依赖项, 每次返回新的callback
Promise.resolve().then(callback)
// 或者
// queueMicrotask(callback)
lastDependencies = dependencies
}
return lastCallback
}
useRef
let lastRef
function useRef(initialRef) {
lastRef = lastRef || initialRef
return {
current: lastRef
}
}