Skip to content
import { useState } from 'react';
// eslint-disable-next-line
import { flushSync } from 'react-dom';

let UseStateCom = (props) => {

  const initCount = () => {
    console.log('initCount')
    return 2 * 2 * 2
  }
  // useState需要放在组件最前面调用,不要在函数或语句中进行调用
  const [count, setCount] = useState(0)
  const [count2, setCount2] = useState(0)
  const [info, setInfo] = useState({
    username: 'zack',
    age: 30
  })
  // eslint-disable-next-line
  const [count3, setCount3] = useState(() => {
    return initCount()
  })

  const handleClick = () => {
    /**
     * 在 handleClick 函数里连续调用 setCount 时,
     * 每次调用 setCount 传入的 count 值都是基于初始状态的,
     * 因为 React 还没来得及更新 count 的值。
     * 所以这四次调用相当于传入了 0 + 1、0 + 2、0 + 3、0 + 4,
     * 而 React 会将这些更新合并,最终只会保留最后一次更新,即 count 会被更新为 4
     */
    setCount(count + 1)
    setCount(count + 2)
    setCount(count + 3)
    setCount(count + 4)
  }

  const handleClick2 = () => {
    // count2会被更新为10 : 0 + 1 + 2 + 3 + 4
    setCount2((count2) => count2 + 1)
    setCount2((count2) => count2 + 2)
    setCount2((count2) => count2 + 3)
    setCount2((count2) => count2 + 4)
  }

  const hanldeAutoClick = () => {
    // 所谓自动批处理,就是我更新2个state值,组件只会渲染一次
    /**
     * 可以使用flushSync取消自动批处理
     * 【组件被渲染!!】会打印2次
      flushSync(() => {
        setCount(count + 1)
      })
      flushSync(() => {
        setCount2(count2 + 1)
      })
     * 
     */

    setCount(count + 1)
    setCount2(count2 + 1)
  }

  console.log("组件被渲染!!");

  // 特性2: useState中的值在修改的时候,并不会进行原值的合并处理
  const hanldeModifyInfo = () => {
    // 只修改一个username,age就丢了
    // setInfo({
    //   username: 'zheng'
    // })
    setInfo({
      ...info,
      username: 'zheng'
    })
  }


  // 特性3: 惰性初始state
  // initCount
  /**
   * 惰性初始 state 允许我们传入一个函数作为 useState 的参数,
   * 这个函数只会在组件的初始渲染时被调用一次,其返回值会作为初始 state。
   * 后续组件重新渲染时,这个函数不会再被调用,从而避免了不必要的重复计算。
   * 
   */

  

  return (
    <div>
      <button onClick={handleClick}>点击1</button>
      <div>count1的值,{count}</div>
      <hr />
      <button onClick={handleClick2}>点击2</button>
      <div>函数式更新:count2的值,{count2}</div>
      <hr />
      <button onClick={hanldeAutoClick}>自动批处理</button>
      <hr />
      <p>我的姓名是: {info.username}, 年龄是: {info.age}</p>
      <button onClick={hanldeModifyInfo}>点击修改信息</button>
      <hr />
      <p>count3的值:{count3}</p>
    </div>
  )
}

export default UseStateCom