useState使用和原理

640?wx_fmt=png


Hooks 是 React 16 中的特性,解决函数组件想使用类组件的一些特性。

关于更多 Hooks 介绍,请参考 React 官网[1]

useState

之前是在类组件中使用状态通过 state 定义,大概代码是这样的。


 
 
import React from 'react';	
class Counter extends React.Component {	
  state = {	
    number: 0	
  }	
  handleClick = () => {	
    this.setState({	
      number: this.state.number + 1	
    })	
  }	
  render() {	
    return (	
      <>	
        <p>{this.state.number}</p>	
        <button	
          onClick={ this.handleClick }>	
          改数字	
        </button>	
      </>	
    );	
  }	
}	
function render() {	
  ReactDOM.render(<Counter />, document.getElementById('root'));	
}	
render()


但是函数组件没有实例,也没有状态。函数组件使用状态需要使用 useState 钩子。


关于 useState 的用法是,需要传入一个参数作为状态的初始值,当函数执行后会返回两个值,一个是当前状态的属性,一个是修改状态的方法。


我们通过一个计数器的例子,当点击按钮表示状态加1。


 
 
import React, {useState} from 'react';	
function Counter() {	
  const [	
    number,	
    setNumber	
  ] = useState(0)	
  return (	
    <>	
      <p>{number}</p>	
      <button	
        onClick={	
          () => setNumber(number + 1)	
        }	
      >	
        改数字	
      </button>	
    </>	
  )	
}	
function render() {	
  ReactDOM.render(<Counter />, document.getElementById('root'));	
}	
render()


现在我们已经掌握了它的用法,那么我们开始分析它的原理。

原理

我们需要写一个 useState 方法,会返回当前状态的属性和设置状态的方法,每当状态改变之后,方法中会调用刷新视图的 render 方法。


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


再次尝试之前的代码,依然可以正常使用,但是当多个 useState 存在的时候就有问题了,只能变一个状态了。


 
 
function Counter() {	
  const [	
    number,	
    setNumber	
  ] = useState(0)	
  const [	
    title,	
    setTitle	
  ] = useState('随机标题')	
  return (	
    <>	
      <h1>{title}</h1>	
      <p>{number}</p>	
      <button	
        onClick={	
          () => setNumber(number + 1)	
        }	
      >	
        改数字	
      </button>	
      <button	
        onClick={	
          () => setTitle(`随机标题${Math.random()}`)	
        }	
      >	
        改标题	
      </button>	
    </>	
  )	
}


现在我们需要优化我们的 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]	
}	
	
function Counter() {	
  const [	
    number,	
    setNumber	
  ] = useState(0)	
  const [	
    title,	
    setTitle	
  ] = useState('随机标题')	
  return (	
    <>	
      <h1>{title}</h1>	
      <p>{number}</p>	
      <button	
        onClick={	
          () => setNumber(number + 1)	
        }	
      >	
        改数字	
      </button>	
      <button	
        onClick={	
          () => setTitle(`随机标题${Math.random()}`)	
        }	
      >	
        改标题	
      </button>	
    </>	
  )	
}	
	
function render() {	
  index = 0	
  ReactDOM.render(<Counter />, document.getElementById('root'));	
}	
render()


现在已经完成了 useState 的基本原理,当你了解原理之后,使用 Hooks 就变得更加容易了。

References

[1] React 官网: https://reactjs.org/docs/hooks-state.html


评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值