React - Hooks 使用(函数组件中使用 React 特性)
创始人
2024-03-26 06:04:09
0

React - Hooks 使用(函数组件中使用 React 特性)

  • 一. 为什么要使用 HOOKS?
  • 二. HOOKS 概念
  • 三. HOOKS 用法
    • 1. useState
      • 1.1 参数及返回值
      • 1.2 setState 两种写法
      • 1.3 setState 示例
    • 2. useEffect
      • 2.1 useEffect 实例
    • 3. useRef
      • 3.1 useRef 实例
  • 四. 一个 Hooks 组件实例

  1. Hook 是React 16.8.0版本增加的新特性/新语法
  2. 可以在函数组件中使用 state 以及其他的 React 特性

一. 为什么要使用 HOOKS?

  • React的组件创建方式,一种是类组件,一种是函数组件。
  • 函数组件相比较类组件,具有以下特点:
    (1)函数组件没有状态
    (2)函数组件没有生命周期
    (3)函数组件没有this
  • 这就说明函数组件,只能做UI展示的功能,涉及到状态的管理与切换,就不得不用类组件或者redux。
  • 在这种情况下,如果想使用函数组件编写一个完整的功能,就可以使用 HOOKS

二. HOOKS 概念

  1. Hook 是React 16.8.0版本增加的新特性/新语法
  2. 可以在函数组件中使用 state 以及其他的 React 特性

三. HOOKS 用法

  1. State Hook:React.useState()
  2. Effect Hook:React.useEffect()
  3. Ref Hook:React.useRef()

1. useState

使函数组件也可以有 state 状态, 并进行状态数据的读写操作。

import { useState } from "react";const [state, setState] = useState(initState);

1.1 参数及返回值

  • initState: useState 参数
    在初始渲染期间,指定state值在内部作缓存
  • [state, setState]: useState 返回值,包含两个元素的数组,
    第一个参数:为内部当前的state状态值,
    第二个参数:为更新state状态值的函数

1.2 setState 两种写法

  1. 第一种写法

    setState(newState);
    

    参数为 非函数值直接指定新的状态值,内部用其覆盖原来的状态值

  2. 第二种写法

    setState(state => {// state : 原本的state值return newState
    });
    

    参数为函数,接收原本的状态值返回新的状态值,内部用其覆盖原来的状态值

1.3 setState 示例

const [count, setCount] = useState(0);setCount(count + 1);setCount((count) => {// count : 原本的state值return count + 1;
});

2. useEffect

在函数组件中执行副作用操作(用于模拟类组件中的生命周期钩子)
可以用来更好的处理副作用,比如 添加订阅、设置定时器、接口请求 以及执行其他包含副作用的操作

import { useEffect } from "react";useEffect(() => {// 在此可以执行任何带副作用操作return () => { // 在组件卸载前执行// 在此做一些收尾工作, 比如清除定时器/取消订阅等};},[stateValue],// 如果指定的是[], 回调函数只会在第一次render()后执行
);

可以把 useEffect Hook 看做如下三个函数的组合:

  • componentDidMount()
  • componentDidUpdate()
  • componentWillUnmount()

2.1 useEffect 实例

const [count, setCount] = useState(0);
useEffect(() => {// 定时器let timer = setInterval(() => {setCount((count) => count + 1);}, 1000);return () => {// 清除定时器clearInterval(timer);};
}, []);

3. useRef

可以在函数组件中存储/查找组件内的标签或任意其它数据
作用:保存标签对象,功能与React.createRef()一样

import { useRef } from "react";const refContainer = useRef(initValue);

3.1 useRef 实例

myRef} type="text" />
const myRef = useRef();function showInputValue() {console.log(myRef.current.value);
}

四. 一个 Hooks 组件实例

类组件 对比 函数组件
实现 state 状态修改、定时器、输入框信息打印、组件卸载

  1. 类组件 实现

    src/index.js 暴露 root

    import React from "react";
    import ReactDOM from "react-dom/client";
    import App from "./App";
    import { BrowserRouter } from "react-router-dom";const root = ReactDOM.createRoot(document.getElementById("root"));
    root.render(
    );
    export default root;
    
    import React, { Component } from "react";
    import { createRef } from "react";
    import root from "../../index";//引入root路径
    export default class index extends Component {state = {count: 0,name: "tom",};myRef = createRef();componentDidMount() {this.timer = setInterval(() => {this.setState({count: this.state.count + 1,});}, 1000);}componentWillUnmount() {clearInterval(this.timer);}increment = () => {this.setState((state) => {return {count: state.count + 1,};});};updateName = () => {this.setState({name: "小明",});};unMount = () => {root.unmount();};showInputValue = () => {console.log(this.myRef.current.value);};render() {return (

    数值为:{this.state.count}

    名字:{this.state.name}





    this.myRef} type="text" />
    );} }
  2. 函数组件 实现

    src/index.js 暴露 root

    import React from "react";
    import ReactDOM from "react-dom/client";
    import App from "./App";
    import { BrowserRouter } from "react-router-dom";const root = ReactDOM.createRoot(document.getElementById("root"));
    root.render(
    );
    export default root;
    
    import { useState, useEffect, useRef } from "react";
    import root from "../../index";//引入root路径
    function Index() {const [count, setCount] = useState(0);const [name, setName] = useState("tom");const myRef = useRef();useEffect(() => {let timer = setInterval(() => {setCount((count) => count + 1);}, 1000);return () => {clearInterval(timer);};}, []);function increment() {// setCount(count + 1);// 第一种写法setCount((count) => {return count + 1;});}function updateName() {setName("小明");}function unMount() {root.unmount();}function showInputValue() {console.log(myRef.current.value);}return (

    数值为:{count}

    名字:{name}





    myRef} type="text" />
    ); }export default Index;
  3. 组件实现效果图
    在这里插入图片描述

相关内容

热门资讯

不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
APK正在安装,但应用程序列表... 这个问题可能是由于以下原因导致的:应用程序安装的APK文件可能存在问题。设备上已经存在同名的应用程序...
安卓文字转语音tts没有声音 安卓文字转语音TTS没有声音的问题在应用中比较常见,通常是由于一些设置或者代码逻辑问题导致的。本文将...
报告实验.pdfbase.tt... 这个错误通常是由于找不到字体文件或者文件路径不正确导致的。以下是一些解决方法:确认字体文件是否存在:...