React Hooks(useCallback、useMemo、useRef)

295 阅读2分钟

我正在参加「掘金·启航计划」

一、useCallback(记忆函数)

防止因为组件重新渲染,导致方法被重新创建,起到缓存作用,只有第二个参数变化了,才重新声明一次。

新建 UseCallback.js方法组件,写入代码:

import React, { useCallback, useState } from 'react'

export default function UseCallback() {

  const [count, setCount] = useState(0)

  const addHandle = useCallback(
    () => {
        setCount(count+1)
    },
    [count]
  )
    
  return (
    <div>
        <button onClick={addHandle}>click</button>
        {count}
    </div>
  )
}

效果: 在这里插入图片描述 可以看到我们使用了useCallback将函数给记忆起来了,为了使其他状态改变而不重新创建不该创建的函数,只有当依赖项count发生改变时才会重新创建。从一定意义上来说提高了性能。


二、useMemo(记忆组件)

useCallback的功能完全可以由useMemo所取代,如果你想通过使用useMemo返回一个记忆函数也是完全可以的。

我们将之前案例选项卡的子组件Cinema.js类组件改成函数组件,并且使用useMemo

import React, { useEffect, useMemo, useState } from 'react'
import axios from 'axios'


export default function UseCallback() {

  const [cinemaList, setCinemaList] = useState([])
  const [text, setText] = useState('')

  useEffect(() => {
    axios({
        url: 'https://m.maizuo.com/gateway?cityId=110100&ticketFlag=1&k=3085018',
        method: 'get',
        headers: {
            'X-Client-Info':' {"a":"3000","ch":"1002","v":"5.2.0","e":"1646314068530784943341569"}',
            'X-Host': 'mall.film-ticket.cinema.list'
        }
    }).then((res) => {
        console.log(res.data)
        setCinemaList(res.data.data.cinemas)
    }).catch((err) => {
        console.log(err)
    })
  },[])

  const getCinemaList = useMemo(() => cinemaList.filter(item => item.name.toUpperCase().includes(text.toUpperCase()) || 
  item.address.toUpperCase().includes(text.toUpperCase())), [cinemaList, text]) // useMemo会执行函数并返回执行后的结果
    
  return (
    <div>
        <input value={text} onChange={(event) => {
              setText(event.target.value)
            }}></input>
            {
                getCinemaList.map((item) => 
                <dl key={item.cinemaId}>
                    <dt>{item.name}</dt>
                    <dd>{item.address}</dd>
                </dl>
                )
            }
    </div>
  )
}

效果: 在这里插入图片描述 可以看到我们使用了函数式组件的hooks成功将之前类组件给重构出来了,并且也是相当的方便。


三、useRef(保存引用值)

新建useRef.js组件,写入代码:

import React, { useRef, useState } from 'react'

export default function UseRef() {

    // let [name, setName] = useState('')
    const name = useRef()
    let [list, setList] = useState(['000', '111', '222'])

    let btnHandle = () => {
        let newList = [...list]
        setList([...newList, name.current.value])
        name.current.value = ''
    }

    let delHandle = (key) => {
        let temList = [...list]
        temList.splice(key, 1)
        setList(temList)
    }

    return (
        <div>
            <input ref={name}></input>
            <button onClick={btnHandle}>click</button>
            <ul>
                {list.map((value, key) => {
                    return <li key={key}>{value} <button onClick={(key) => delHandle(key)}>删除</button></li>
                })}
            </ul>
        </div>
    )
}

效果: 在这里插入图片描述 不仅如此,useRef还能在函数组件中保持状态:

import React, { useState, useRef } from 'react'

export default function UseRef() {

    const [count, setCount] = useState(0)

    let myCount = useRef(0)

    const addHandle = () => {
        setCount(count + 1)
        myCount.current++
    }

    return (
        <div>
            <button onClick={addHandle}>click</button>
            {count} - {myCount.current}
        </div>
    )
}

在这里插入图片描述

在学习React的路上,如果你觉得本文对你有所帮助的话,那就请关注点赞评论三连吧,谢谢,你的肯定是我写博的另一个支持。