React框架学习(三) hooks基本使用

一.为什么要有hooks?

1.想要复用一个class类组件太麻烦

react的核心就是将一个页面拆成一堆独立的,可复用的组件,自上而下的单向数据流的形式将组件串联起来,在使用class类组件时,他自身就有state状态,所以复用起来就很麻烦,官方的解决方案是:使用渲染属性Render Props和高阶组件Higher-OrderComponents,但是这两种方式会增加代码的层级关系,所以还是hooks比肩简洁

2.生命周期中的钩子函数逻辑太乱

一般情况,如果项目较大,网络请求等就会很繁多,在维护项目时就会变得不直观

3.创建组件时,this指向的问题

有时候写了一个无状态的简洁组件,但后期有需求变动,就得改为class类组件,又的很麻烦费时间

 二.hooks函数

1.useState (状态) 使用

useState是react自带的一个hooks函数,作用是用来声明状态变量,接收的参数是状态的初始值,返回一个数组,数组第0项就是当前值,第1项时可以改变这个状态值的方法函数,一般都使用ES6解构的方式,将第一个参数与第二个参数解构出来

import { useState } from 'react'

const Count = () => {
  // 错误演示:
  // if (Math.random() > 0.5) {
  //   const [loading, setLoading] = useState(false)
  // }
  // for (let index = 0; index < [].length; index++) {
  //   const [loading1, setLoading1] = useState(false)
  // }
  // const handleClick = () => {
  //   const [loading2, setLoading3] = useState(false)
  //   setCount(count + 1)
  // }

  const [count, setCount] = useState(0)
  const [loading, setLoading] = useState(false)

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

  return (
    <div>
      <h1>计数器:{count}</h1>
      <button onClick={handleClick}>+1</button>
    </div>
  )
}

export default function App() {
  return (
    <div>
      <Count></Count>
    </div>
  )
}

2.useEffect (副作用函数) 使用

useEffect副作用函数,有两个参数,第一个参数是一个回调函数,在这里执行逻辑判断,第二个参数是一个数组,表示依赖项,useEffect函数只执行一次,但有时候当数据发生变化的时候,需要再次执行,就需要用到第二个依赖参数,当参数发生改变时,就会再次执行当前函数

import { useState, useEffect } from 'react'

const Count = () => {
  const [count, setCount] = useState(0)
  const [loading, setLoading] = useState(false)

  // 第二个参数:表示 effect 的依赖项,
  // 也就是说:只有在数组中的 依赖项 改变时 effect 回调才会执行
  useEffect(() => {
    console.log('count', count)
    document.title = `点击了 ${count} 次`
  }, [count])
  // }, [count, loading])

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

  return (
    <div>
      <h1>计数器:{count}</h1>
      <button onClick={handleClick}>+1</button>
      <hr />
      <div>{loading ? '加载中' : '加载完成!!!'}</div>
      <button onClick={() => setLoading(!loading)}>切换loading</button>
    </div>
  )
}

export default function App() {
  return (
    <div>
      <Count></Count>
    </div>
  )
}

useEffect与useLayoutEffect区别

推荐使用useEffect,他会在页面DOM树以及渲染完成后执行,性能会更高,而useLayoutEffect是在DOM树更新完成后执行,会阻塞页面渲染,但如果只做DOM修改就使用useLayoutEffect,因为这样做出的更改会一起被渲染,只有一次回流,重绘的代价。

3.useCallback (记忆函数) 使用

防止组件重新渲染,导致方法重新被创建,起到缓存作用,只有第二个参数变化了,才重新声明一次,如果第二个依赖参数为空,则始终使用当前记忆的参数值,不会重新读取

4.useMemo (记忆组件) 使用

等价于useCallback,他会执行第一个函数并将结果返回,与vue的计算属性基本一致,会返回一个结果,并进行缓存

5.useRef (保存引用值) 使用

类似于React.creactRef(),绑定谁就能获取谁,使用ref绑定useRef,可以绑定标签,组件等,通过useRef可以在hooks函数中保存变量,

6.useContext 和useReducer 使用

useContext  跨级通讯,如果想要组件之间共享状态,可以使用useContext。React 的 Context API 是一种在应用程序中深入传递数据的方法,

使用 Context ,首先顶层先声明 Provier 组件,并声明 value属性,接着在后代组件中声明 Consumer 组件,这个 Consumer子组件,只能是唯一的一个函数,函数参数即是 Context 的负载。如果有多个 Context ,ProviderConsumer任意的顺序嵌套即可。

useReducer 接收两个参数,第一个参数:reducer函数,第二个参数:初始化的state,返回值为最新的state和dispatch函数(用来触发reducer函数,计算对应的state)

7.自定义hooks

当你在一个项目中发现大量类似代码,那就抽离成Hooks

比如我们多个页面有相同的请求方法

// 以use开头
export const useUserData = (category: string[], labelName?: string) => {
  const [baseTotal, setBaseTotal] = useState<number>(0)

  useEffect(() => {
    dealSearchTotal(category, labelName)
  }, [labelName, category])
  const dealSearchTotal = async (
  ) => {
    const data = await getUserData(curCategory, labelName)
    const { baseTotal, calculateTotal, basicTotal, extTotal } = data
    setBaseTotal(baseTotal)
  }
  // 最后return出想要的数据
  return [baseTotal, calculateTotal, basicTotal, extTotal]
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值