自定义Hook

定义

自定义hook是一个函数,函数内部调用了其他hook函数,且以use开头命名,从而可称为自定义hook

其主要,是让代码拥有更好的重用性,依旧是函数式思维

基础使用

如计数器

import React, { useState } from "react"

export default function App() {
  const [count, setCount] = useState(0)
  
  return (
  <div>
    <p>当前数值:{count}</p>
    <button onClick={() => setCount(count + 1)}>
      增加
    </button>
    <button onClick={() => setCount(count - 1)}>
      减少
    </button>
  </div>
  )
}

将其改写成自定义hook形式,虽然对于计数器来说,可能有点哗众取宠

import React, { useState } from "react"

function useCount(initValue: number) {
  const [count, setCount] = useState(initValue)
  const add = () => setCount(count + 1)
  const sub = () => setCount(count - 1)
  return [count, add, sub] as [number, () => void, () => void]
}

export default function App() {
  const [count, add, sub] = useCount(0)
  return (
    <div>
      <p>当前数值:{count}</p>
      <button onClick={add}>
        增加
      </button>
      <button onClick={sub}>
        减少
      </button>
    </div>
  )
}

其优势可见于

  • 复用性,可批量生产
  • 修改权限封闭,对外界只提供两个访问函数

组合使用

如果将useState()useEffect()组合起来使用会如何?
一个常见的场景,异步加载下拉框选项

import React, { useEffect, useState } from "react"

interface Option {
  key: number
  value: number
  label: string
}

export default function App() {
  const [options, setOptions] = useState<Option[]>([])
  useEffect(() => {
    setTimeout(() => {
      setOptions([{ key: 1, value: 1, label: '1' }])
    }, 100)
  }, [])

  return (
    <div>
      <select>
        <option value={0}>--- 请选择 ---</option>
        {options.map(item => <option {...item} />)}
      </select>
    </div>
  )
}

存在多个下拉框时,其逻辑是一致的

const [options1, setOptions1] = useState<Option[]>([])
const [options2, setOptions2] = useState<Option[]>([])
const [options3, setOptions3] = useState<Option[]>([])
useEffect(() => {
  setTimeout(() => {
    setOptions1([{ key: 1, value: 1, label: '1' }])
    setOptions2([{ key: 2, value: 2, label: '2' }])
    setOptions3([{ key: 3, value: 3, label: '3' }])
  }, 100)
}, [])

将其提取为自定义hook,大多数情况下,只需要暴露options即可

function useOptions(url: string) {
  const [options, setOptions] = useState<Option[]>([])
  useEffect(() => {
    axios.get<Option[]>(url).then(({ data }) => setOptions(data))
  }, [])
  return options
}

到了这一步,非常自然的,将其提取为一个组件

import React from "react"
import { useOptions } from "../hooks"

export default function Select({ url }: { url: string }) {
  const options = useOptions(url)
  return (
    <select>
      <option value={0}>--- 请选择 ---</option>
      {options.map(item => <option {...item} />)}
    </select>
  )
}

useOption()还能单独使用,并没有粘合在其中,灵活性很高

小结

自定义hook主要特点

  • 函数本能,多处重用
  • 如同创建对象,只提供特定的数据与修改函数,封闭不必要的访问途径
  • 自定义hook可继续嵌套组合,也是组件思想
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值