React Hooks系列之useState

前言

react hooks 是 React 16.8 的新增特性。 它可以让我们在函数组件中使用 state 、生命周期以及其他 react特性,而不仅限于 class 组件。react hooks 的出现,标示着 react中不会在存在无状态组件了,只有类组件和函数组件。具体可查看官网

优势:

  1. 函数组件不能使用state,遇到交互更改状态等复杂逻辑时不能更好地支持,hooks让函数组件更靠近class组件,拥抱函数式编程。
  2. 解决副作⽤问题,hooks出现可以处理数据获取、订阅、定时执行任务、手动修改 ReactDOM这些⾏为副作用,进行副作用逻辑。比如useEffect。
  3. 更好写出有状态的逻辑重用组件。
  4. 让复杂逻辑简单化,比如状态管理:useReducer、useContext。
  5. 函数式组件比class组件简洁,开发的体验更好,效率更⾼,性能更好。
  6. 更容易发现无用的状态和函数。

useState介绍

const [state, setState] = useState(initialState);

返回一个 state,以及更新 state 的函数setState。

  • state是要设置的状态 。
  • setState是更新state的方法。setState 函数用于更新 state。它接收一个新的 state 值并将组件的一次重新渲染加入队列。
  • initState是初始的state,可以是随意的数据类型,也可以是回调函数,但是函数必须是有返回值(惰性state)。

惰性初始 state initialState 参数只会在组件的初始渲染中起作用,后续渲染时会被忽略。如果初始 state需要通过复杂计算获得,则可以传入一个函数,在函数中计算并返回初始的 state,此函数只在初始渲染时被调用:

const [state, setState] = useState(() => {   
	  const initialState = someExpensiveComputation(props);   
	  return initialState;
}); ```

在初始渲染期间,返回的状态 (state) 与传入的第一个参数 (initialState) 值相同。

setState(newState);

在后续的重新渲染中,useState 返回的第一个值将始终是更新后最新的 state。

useState原理

我们需要写一个 useState 方法,会返回当前状态和设置状态的方法,每当状态改变之后,方法中会调用刷新视图的 render 方法。状态我们需要放在最外面,方便下次执行函数时可以重新取值。初始状态只会在函数第一次执行的时候赋值。

let memoizedState;
function useState (initialState) {
  memoizedState = memoizedState || initialState
  function setState (newState) {
    memoizedState = newState
    render()
  }
  return [memoizedState, setState]
}

这样确实是可以正常使用,但是当多个 useState 存在的时候就有问题了,只能变一个状态了。现在我们需要优化我们的 Hooks ,解决多个 useState 同时使用的问题,当多个状态存在的时候,我们需要使用数组保存状态。

let memoizedStates = []
let index = 0
function useState (initialState) {
  memoizedStates[index] = memoizedStates[index] || initialState
  let currentIndex = index
  function setState (newState) {
    memoizedStates[currentIndex] = newState
    render()
  }
  return [memoizedStates[index++], setState]
}

useState使用

例子:

  function App () {
    const [ count, setCount ] = useState(0)
    return (
      <div>
        点击次数: { count } 
        <button onClick={() => { setCount(count + 1)}}>点我</button>
      </div>
      )
  }

相同值,当我们在使用 useState 时,修改值时传入同样的值,我们的组件是不会渲染的。

  function App () {
    const [ count, setCount ] = useState(0)
    console.log('我就看你渲染不')
    return (
      <div>
        点击次数: { count } 
        <button onClick={() => { setCount(count)}}>点我</button>
      </div>
      )
  }

发布了82 篇原创文章 · 获赞 46 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/weixin_43720095/article/details/104946468