React18 Hooks【useState、useEffect等】

本文介绍了React18中引入的Hooks特性,包括useState用于添加状态管理,useEffect实现生命周期功能,useRef用于操作DOM元素或组件对象,以及useReducer在复杂状态管理中的应用。这些Hooks简化了函数组件的编写,使得它们能像类组件一样处理状态和生命周期。
摘要由CSDN通过智能技术生成

React18 Hooks

默认情况下,React函数组件是没有状态state的、没有生命周期的。react16版本后,新增了useStateuseEffect等钩子函数,让现在的函数组件具有了之前类组件的同等效力。解决了类组件在实际开发中的一些痛点

1、useState

让函数组件拥有了状态,类似Vue中的ref、reative。开发中,为了让数据更新视图,才会赋予这个数据以状态,否则这个数据还是作为普通局部变量的好

import { useState } from 'react'

const Home = () => {
  const [count, setCount] = useState(0)
  const add = () => {
    setCount(count + 1)
  }
  return (
    <>
     	<span>{count}</span>
      	<button onClick={add}>+</button>
    </>
  )
}
export default Home

**注意: **

  • setCount会更新组件
  • set函数 只影响 下一次 渲染中 useState 返回的内容。所以在set函数后面获取的是旧值

2、useEffect

让函数组件拥有生命周期,useEffecthook即是:类组件中componentDidMount、componentDidUpdate、componentWillUnmounted这三个钩子的功能组合

import { useState, useEffect } from 'react'

const Home = () => {
  const [count, setCount] = useState(0)
  const add = () => {
    setCount(count + 1)
  }
  // 接收一个参数时:组件加载完成和组件状态更新时 执行
  useEffect(function () {
    console.log('zhw')
  })
  
  // 如果只希望函数挂载完后,执行一次,组件状态变化不再执行,可以传空数组
  useEffect(function () {
    console.log('zhw')
  }, [])
  
  // 接收参数二时,参数二是一个数组,用于指定依赖数据,用于当依赖数据变化时,执行一次回调
  // 1、组件挂载完后执行一次;2、仅仅当count的状态更新,执行一次
  useEffect(function () {
    console.log('zhw')
  }, [count])

  // 组件卸载之前按
  // 1、
  useEffect(function () {
    return function () {
      // 该子函数会在组件    即将卸载  和   状态更新 的时候,自动执行
      console.log('组件卸载了')
    }
  })  
  // 2、
  useEffect(function () {
    return function () {
      // 该子函数会在组件    仅仅在 即将卸载  的时候,自动执行
      console.log('组件卸载了')
    }
  }, []) 
  return (
    <>
    	<span>{count}</span>
      	<button onClick={add}>+</button>
    </>
  )
}
export default Home

3、useRef

允许在函数组件中使用ref属性 操作元素或者组件对象,useRef底层使用的就是createRef

  1. 获取单个元素对象
import React, { useState, useRef } from 'react'

const Home = () => {
  const [count, setCount] = useState(0)
  // React.MutableRefObject<HTMLHtmlElement>: 因为numRef 可能undefined
  const numRef = useRef() as React.MutableRefObject<HTMLHtmlElement>

  const add = () => {
    setCount(count + 1)
    // useRef().current: 获取元素或者组件对象
    console.log(numRef.current)
  }
  return (
    <>
      <button onClick={add}>+</button>
      <span ref={numRef}>{count}</span>
    </>
  )
}
export default Home
  1. 获取列表元素对象

只需借用ref属性,不需要使用useRef()

const Home = () => {
  const hobbies = ['唱跳', 'rap', '篮球']
  // 这块使用普通对象
  const hobbyRefList: HTMLElement[] = []

  const getHobbyEle = () => {
    // 更新rap背景色
    hobbyRefList[1].style.background = 'skyblue'
  }
  return (
    <>
      <ul>
        {hobbies.map((item) => (
          <li
            ref={(el: HTMLLIElement) => {
              hobbyRefList.push(el)
            }}
            key={item}
          >
            {item}
          </li>
        ))}
      </ul>
      <button onClick={getHobbyEle}>获取爱好列表元素对象</button>
    </>
  )
}
export default Home
  1. 获取函数组件对象

react18中无法直接通过ref属性获取组件对象,因为react18中,函数组件没有实例。直接使用ref会报错: Function components cannot be given refs。既然无法获取实例,则需要想其他办法,获取组件状态和方法.此时可以使用React内置的高阶组件:React.forwardRef: 用于处理函数组件,可以将ref属性传递到函数组件内部

子组件中

import { useState, forwardRef, useImperativeHandle } from 'react'

// props: 父组件通过自定义属性传递的数据
// ref: 把父组件传递的ref属性和函数子组件元素建立对应关系
const Header = (props: object, ref: any) => {
  console.log(props, ref)

  const [title, setTitle] = useState('头部组件')
  // 用于子组件 向父组件 暴露方法
  // 类似于Vue3的 defineExpose
  useImperativeHandle(ref, () => ({
    updateTitle: (title: string) => {
      setTitle(title)
    }
  }))

  return (
    <>
      <div ref={ref}>{title}</div>
    </>
  )
}

export default forwardRef(Header)

关键词: forwardRefuseImperativeHandle


父组件中

import { useRef } from 'react'
import Header from '@/components/Header'

const Home = () => {
  // useRef利用泛型 可以自动推导类型为: React.MutableRefObject<HTMLElement | undefined>
  // 解决: 类型“(instance: HTMLDivElement | null) => void”上不存在属性“current”
  const funCompRef = useRef<HTMLElement>()

  const getHobbyEle = () => {
    console.log(funCompRef.current)
  }
  return (
    <>
      <Header ref={funCompRef} />
      <button onClick={getHobbyEle}>获取爱好列表元素对象</button>
    </>
  )
}
export default Home

4、useReducer 【了解】

复杂场景下,使用useReducer创建状态数据。类似于react-redux,一般建议直接使用react-redux即可

import { useReducer } from 'react'

interface IAction {
  type: string
  payload: number // any
}
const Home = () => {
  // initHobby: hobbies的状态初始值
  const initHobby = ['篮球', 'rap', '唱跳']
  // 操作state的具体逻辑
  // action: {type:'操作类型', payload: 操作state时的外部传参}
  const hobbyReducer = (state = initHobby, action: IAction) => {
    switch (action.type) {
      // 删除操作
      case 'hobby/del':
        state.splice(action.payload, 1)
        // 最后一定要返回一个全新的数据对象
        return [...state]
      default:
        return state
    }
  }
  // useReducer(操作state的reducer回调函数,状态数据的初始值)
  // 返回值: [视图最终用到的状态数据, 更新状态数据的方法dispatch]
  // dispatch(): 发送数据操作对象action: {type:'操作类型', payload: 操作state时的外部传参}给reducer函数,
  // 根据type完成不同type下的数据操作逻辑
  const [hobbies, dispatch] = useReducer(hobbyReducer, initHobby)

  const del = (index: number) => {
    dispatch({
      type: 'hobby/del',
      payload: index
    })
  }
  return (
    <>
      <ul>
        {hobbies.map((item, index) => (
          <li key={item}>
            {item}
            <button
              onClick={() => {
                del(index)
              }}
            >
              删除
            </button>
          </li>
        ))}
      </ul>
    </>
  )
}
export default Home

注意: 实际开发中,一版都会使用react-redux替换useReducer

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
useStateReact Hooks提供的一个函数,用于在函数式组件中声明和使用状态。它接受一个初始值作为参数,并返回一个包含当前状态和更新状态的数组。useState的作用类似于类组件中的this.state和this.setState方法,但是在函数式组件中使用更加简洁方便。 useEffect也是React Hooks提供的一个函数,用于在函数式组件中执行副作用操作,比如订阅事件、发送网络请求、操作DOM等。它接受两个参数,第一个参数是一个回调函数,用于执行副作用操作,第二个参数是一个依赖数组,用于指定何时重新执行副作用操作。useEffect的作用类似于类组件中的生命周期方法,比如componentDidMount、componentDidUpdate和componentWillUnmount。 useCallback也是React Hooks提供的一个函数,用于在函数式组件中缓存回调函数。它接受一个回调函数和一个依赖数组作为参数,并返回一个经过缓存的回调函数。useCallback的作用是在依赖数组不变的情况下,避免不必要的函数重新创建,提高性能。 综上所述,useState用于声明和使用状态,useEffect用于执行副作用操作,而useCallback用于缓存回调函数。它们都是React Hooks提供的函数,可以在函数式组件中方便地使用。 <span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [搞懂React Hooks之 useState, useCallback, useEffect, useRef ,useMemo和useEffect](https://blog.csdn.net/qq_27401917/article/details/116699141)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [学习记录431@reactuseStateuseEffectuseCallback](https://blog.csdn.net/weixin_44663675/article/details/119121498)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

原谅我很悲

不要打赏哦,加个好友一起学习呗

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值