美文网首页
六、useState

六、useState

作者: sweetBoy_9126 | 来源:发表于2024-03-29 19:01 被阅读0次

用法

const [count, setCount] = useState(0)

const handleClick = () => {
  setCount((count) => count + 1)
}

实现:

  1. 要返回一个数组,第一个是当前的 state,第二个是修改 state 的方法
const useState = (inital) => {
  const stateHook = {
    state: inital
  }

  const setState = (action) => {
    stateHook.state = action(stateHook.state)
  }

  return [stateHook.state, setState]
}
  1. 更新页面使用直接的 update 里的逻辑修改 wipRoot
  let currentFiber = wipFiber


  const setState = (callback) => {
    stateHook.state =  callback(stateHook.state)
    wipRoot = {
      ...currentFiber,
      alternate: currentFiber
    }
    nextWorkOfUnit = wipRoot
  }
  1. 因为每次我们更新页面我们的state 的值都会重置所以我们需要存储我们的 state 的值,存在我们之前的 fiber 上
const useState = (state) => {
  let currentFiber = wipFiber
  const oldHook = currentFiber.alternate?.stateHook
  const stateHook = {
    state: oldHook ? oldHook.state : state
  }

  currentFiber.stateHook = stateHook

  const setState = (callback) => {
    stateHook.state =  callback(stateHook.state)
    wipRoot = {
      ...currentFiber,
      alternate: currentFiber
    }
    nextWorkOfUnit = wipRoot
  }

  return [stateHook.state, setState]
}
  1. 实现多个 useState
    上面的 useState 如果我们页面里有多个后面的会把前面的覆盖
  • demo
const Foo = () => {
  console.log('foo render')
  const [count, setCount] = React.useState(0)
  const [age, setAge] = React.useState(1)
  const handleClick = () => {
    setCount((count) => count + 1)
    setAge((age) => age + 2)
  }
  return (
    <div>
      <h1>foo</h1>
      {count}
      {age}
      <button onClick={handleClick}>click</button>
    </div>
  )
}

点击都会每次 +2
解决方式:使用一个数组和索引来对应关系
每次updateFunctionComponent 的时候初始化数组和索引值

let stateHooks
let stateHooksIndex
const updateFunctionComponent = (fiber) => {
+  stateHooks = []
+  stateHooksIndex = 0
  wipFiber = fiber
  const children = [fiber.type(fiber.props)]
  initChildren(fiber, children)
}

const useState = (inital) => {
  let currentFiber = wipFiber
  const oldHook = currentFiber.alternate?.stateHooks[stateHooksIndex]
  const stateHook = {
    state: oldHook ? oldHook.state : inital
  }

  stateHooks.push(stateHook)
  currentFiber.stateHooks = stateHooks

  const setState = (action) => {
    stateHook.state = action(stateHook.state)
    wipRoot = {
      ...currentFiber,
      alternate: currentFiber
    }
    nextWorkOfUnit = wipRoot
  }
  stateHooksIndex++
  return [stateHook.state, setState]
}
  1. 批量处理 action
const useState = (inital) => {
  let currentFiber = wipFiber
  const oldHook = currentFiber.alternate?.stateHooks[stateHooksIndex]
  const stateHook = {
    state: oldHook ? oldHook.state : inital,
    queue: oldHook? oldHook.queue : []
  }
  stateHook.queue.forEach((action) => stateHook.state = action(stateHook.state))
  stateHook.queue = []
  stateHooks.push(stateHook)
  currentFiber.stateHooks = stateHooks

  const setState = (action) => {
    stateHook.queue.push(action)
    wipRoot = {
      ...currentFiber,
      alternate: currentFiber
    }
    nextWorkOfUnit = wipRoot
  }
  stateHooksIndex++
  return [stateHook.state, setState]
}

每次steState 不会直接修改,是在dom重新渲染后才修改

  1. 支持直接传入值
    setAge(4)

  const setState = (action) => {
 +   stateHook.queue.push(typeof action === 'function' ? action : () => action)
...
}
  1. 减少不必要的更新
    我们上面的代码不管我们后面修改的 state和之前一不一样都不重新 render
  const setState = (action) => {
    const eagerState = typeof action === 'function' ? action(stateHook.state) : action
    if (eagerState === stateHook.state) {
      return
    }
  ....
}

相关文章

  • React Hooks——useState的源码流程

    React Hooks——useState 源码版本 16.8 useState 流程示意图 从useState源...

  • React Hooks

    一.useState 提示: useState 最好是在最顶层调用, 组件每次渲染的 useState 数量必须...

  • React Hooks

    一.useState hooks就是在函数组件中使用state通过useState实现的。 useState传入一...

  • 01-React-hooks-useState基本使用

    React-hooks-useState useState的基本用法 格式: 初始状态 useState的第一个参...

  • React-Hooks之保存状态和生命周期

    1.保存状态(useState) useState(initialState) 的参数 initialState ...

  • useState 实现原理

    useState 熟悉hooks的都知道,最常用的useState 大概用法 简单的实现一个useState 先模...

  • hook useEffect

    useState 最简单的 useState 用法是这样的:function Counter() { var [...

  • 常用React Hooks 方法

    useState 使用状态 const [n, setN] = React.useState(0)const [u...

  • reactHooks的使用

    useState的使用 在reactHooks中useState代替了原本的state,const [age,se...

  • Hooks

    useState 说明: 通过useState来定义数据,以及修改方式(即:set方式) 如上:loading即为...

网友评论

      本文标题:六、useState

      本文链接:https://www.haomeiwen.com/subject/wuaptjtx.html