呕心沥血,一文看懂 react hooks 中 useState、useEffect、useContext、useRef、自定义hook

一遍就能学会的 react hooks

介绍

react hooksReact 16.8 的新增特性。 它可以让我们在函数组件中使用 state 、生命周期以及其他 react 特性,而不仅限于 class 组件

react hooks 的出现,标示着 react 中不会在存在无状态组件了,只有类组件和函数组件

对比

存在即合理,hooks 也不例外,它的出现,就代表了它要解决一些 class 组件的缺陷或者不足,那么我们先来看看 class 组件有什么不足或者问题存在

根据网上的说法我总结出三点,当然每种问题都有其解决方案

问题 解决方案 缺点
生命周期臃肿、逻辑耦合
逻辑难以复用 通过继承解决 不支持多继承
通过hoc解决 会增加额外的组件嵌套,也会有一些性能影响
渲染属性 同上、层级臃肿、性能影响
class this 指向问题 匿名函数 每次都创建新的函数,子组件重复不必要渲染
bind 需要写很多跟逻辑、状态无关的代码

hooks 对这些问题都有较好的解决方案

  1. 没有了 class, 自然就没有了 this 指向问题
  2. 通过自定义 useEffect 来解决复用问题
  3. 通过使用 useEffect 来细分逻辑,减小出现逻辑臃肿的场景

当然,hooks 是一把双刃剑,用的好自己能够达到效果,用的不好反而会 降低开发效率和质量,那么我们接下来看看如用更好的使用 hooks

具体使用

useState 的使用

简单例子

hooks 的能力,就是让我们在函数组件中使用 state, 就是通过 useState 来实现的,我们来看一个简单的例子

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

useState 的使用非常简单,我们从 React 中拿到 useState 后,只需要在使用的地方直接调用 useState 函数就可以, useState 会返回一个数组,第一个值是我们的 state, 第二个值是一个函数,用来修改该 state 的,那么这里为什么叫 countsetCount?一定要叫这个吗,这里使用了 es6 的解构赋值,所以你可以给它起任何名字,updateCount, doCountany thing,当然,为了编码规范,所以建议统一使用一种命名规范,尤其是第二个值

相同值

当我们在使用 useState 时,修改值时传入同样的值,我们的组件会重新渲染吗,例如这样

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

结果是不会,放心使用

useState 的默认值

useState 支持我们在调用的时候直接传入一个值,来指定 state 的默认值,比如这样 useState(0), useState({ a: 1 }), useState([ 1, 2 ]),还支持我们传入一个函数,来通过逻辑计算出默认值,比如这样

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

这个时候,就有小伙伴问了,那我组件每渲染一次,useState 中的函数就会执行一边吗,浪费性能,其实不会,useState 中的函数只会执行一次,我们可以做个测试

function App (props) {
   
    const [ count, setCount ] = useState(() => {
   
      console.log('useState default value function is call')
      return props.count || 0
    })
    return (
      <div>
        点击次数: {
    count } 
        <button onClick={
   () => {
    setCount(count + 1)}}>点我</button>
      </div>
      )
  }

结果是

setUseState 时获取上一轮的值

我们在使用 useState 的第二个参数时,我们想要获取上一轮该 state 的值的话,只需要在 useState 返回的第二个参数,也就是我们上面的例子中的 setCount 使用时,传入一个参数,该函数的参数就是上一轮的 state 的值


  setCount((count => count + 1)

多个 useState 的情况

useState 我们不可能只使用一个,当我们使用多个 useState 的时候,那 react 是如何识别那个是哪个呢,其实很简单,它是靠第一次执行的顺序来记录的,就相当于每个组件存放useState 的地方是一个数组,每使用一个新的 useState,就向数组中 push 一个 useState,那么当然,当我们在运行时改变、添加、减少 useState 时,react 还能正常执行吗

function App (props) {
   
  let count, setCount
  let sum, setSum
  if (count > 2) {
   
    [ count, setCount ] = useState(0)
    [ sum, setSum ] = useState(10)
  } else {
   
    [ sum, setSum ] = useState(10)
    [ count, setCount ] = useState(0)
  }
  return (
    <div>
      点击次数: {
    count } 
      总计:{
    sum }
      <button onClick={
   () => {
    setCount(count + 1); setSum(sum - 1)}}>点我</button>
    <
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值