useState
useMemo
useReducer

useState

  1. const lastStates = []
  2. let index = 0
  3. function useState(initialState) {
  4. lastStates[index] = lastStates[index] || initialState
  5. const currentIndex = index
  6. function setState(nextState) {
  7. lastStates[currentIndex] = nextState
  8. // render()
  9. }
  10. return [lastStates[index++], setState]
  11. }

useCallback

  1. import { isChanged } from './utils'
  2. let lastCallback
  3. let lastDependencies
  4. function useCallback(callback, dependencies) {
  5. if (lastDependencies) {
  6. if (isChanged(lastDependencies, dependencies)) { // 依赖项改变了, 返回新的callback
  7. lastCallback = callback
  8. lastDependencies = dependencies
  9. }
  10. } else { // 没有依赖项, 每次返回新的callback
  11. lastCallback = callback
  12. lastDependencies = dependencies
  13. }
  14. return lastCallback
  15. }
  16. // export function isChanged(lastDeps, deps) {
  17. // const changed = !lastDeps.every((dep, idx) => {
  18. // return dep === deps[idx]
  19. // })
  20. // return changed
  21. // }

useMemo

  1. import { isChanged } from './utils'
  2. let lastMemo
  3. let lastDependencies
  4. function useMemo(callback, dependencies) {
  5. if (lastDependencies) {
  6. if (isChanged(lastDependencies, dependencies)) {
  7. lastMemo = callback()
  8. lastDependencies = dependencies
  9. }
  10. } else {
  11. lastMemo = callback()
  12. lastDependencies = dependencies
  13. }
  14. }

useReducer

  1. let lastState
  2. function useReducer(reducer, initialState) {
  3. lastState = lastState || initialState
  4. const dispatch = (action) => {
  5. lastState = reducer(lastState, action)
  6. // render()
  7. }
  8. return [lastState, dispatch]
  9. }
  10. // useage
  11. const reducer = (state, action) => {
  12. switch(action.type) {
  13. case 'add':
  14. return state + 1
  15. default:
  16. return state
  17. }
  18. }
  19. cosnt [state, dispatch] = useReducer(reducer, 0)

useContext

  1. function useContext(context) {
  2. return context._currentValue
  3. }

useEffect

  1. import { isChanged } from './utils'
  2. let lastDependencies
  3. // callback在浏览器渲染完成之后执行
  4. function useEffect(callback, dependencies) {
  5. if (lastDependencies) {
  6. if (isChanged(lastDependencies, dependencies)) { // 依赖项改变了, 返回新的callback
  7. setTimeout(callback, 0)
  8. lastDependencies = dependencies
  9. }
  10. } else { // 没有依赖项, 每次返回新的callback
  11. setTimeout(callback, 0)
  12. lastDependencies = dependencies
  13. }
  14. return lastCallback
  15. }

useLayoutEffect

  1. import { isChanged } from './utils'
  2. let lastDependencies
  3. // callback在render之后,浏览器渲染之前执行
  4. function useLayoutEffect(callback, dependencies) {
  5. if (lastDependencies) {
  6. if (isChanged(lastDependencies, dependencies)) { // 依赖项改变了, 返回新的callback
  7. Promise.resolve().then(callback)
  8. // 或者
  9. // queueMicrotask(callback)
  10. lastDependencies = dependencies
  11. }
  12. } else { // 没有依赖项, 每次返回新的callback
  13. Promise.resolve().then(callback)
  14. // 或者
  15. // queueMicrotask(callback)
  16. lastDependencies = dependencies
  17. }
  18. return lastCallback
  19. }

useRef

  1. let lastRef
  2. function useRef(initialRef) {
  3. lastRef = lastRef || initialRef
  4. return {
  5. current: lastRef
  6. }
  7. }