当前位置: 首页 > article >正文

React 18 Hooks:函数组件的强大工具

在这里插入图片描述

🤍 前端开发工程师、技术日更博主、已过CET6
🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1
🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》
🍚 蓝桥云课签约作者、上架课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入门到实战全面掌握 uni-app》
💬 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。

一、背景与用途

在React 18中,Hooks是一种在函数组件中使用React特性的方式,它可以让你在不编写类组件的情况下使用状态(state)和其他React特性。Hooks的出现主要是为了解决函数组件之前无法拥有自身状态和生命周期方法的问题,使得函数组件在功能上更加强大,代码更加简洁和易于理解。

二、常用Hooks

(一)useState

  1. 基本概念与用法
    • useState是一个Hook,用于在函数组件中添加状态。它接收一个初始值作为参数,并返回一个包含两个元素的数组。第一个元素是当前状态的值,第二个元素是一个用于更新状态的函数。
    • 例如,创建一个简单的计数器组件:
    import React, { useState } from 'react';
    
    const Counter = () => {
      const [count, setCount] = useState(0);
      const increment = () => {
        setCount(count + 1);
      };
      return (
        <div>
          <p>Count: {count}</p>
          <button onClick={increment}>Increment</button>
        </div>
      );
    };
    
    • 在这个例子中,useState(0)初始化了一个状态count,初始值为0。setCount是用于更新count状态的函数,当用户点击按钮时,increment函数被调用,通过setCount(count + 1)更新count的值,组件会重新渲染以显示新的计数。
  2. 更新状态的注意事项
    • 不可变数据原则:在更新状态时,要遵循不可变数据原则。例如,如果状态是一个对象或数组,不要直接修改它,而是要返回一个新的对象或数组。错误的做法是:
    const [state, setState] = useState({ value: 0 });
    const wrongUpdate = () => {
      state.value++; // 错误,直接修改状态
      setState(state);
    };
    
    • 正确的做法可以是使用对象展开运算符来返回一个新的对象:
    const [state, setState] = useState({ value: 0 });
    const correctUpdate = () => {
      setState((prevState) => ({
       ...prevState,
        value: prevState.value + 1
      }));
    };
    

(二)useEffect

  1. 基本概念与用法
    • useEffect用于在函数组件中执行副作用操作,例如数据获取、订阅事件、手动修改DOM等。它接收一个函数作为主要参数,这个函数会在组件渲染到屏幕之后执行。
    • 例如,在组件挂载时获取数据:
    import React, { useState, useEffect } from 'react';
    
    const DataFetchingComponent = () => {
      const [data, setData] = useState(null);
      useEffect(() => {
        const fetchData = async () => {
          const response = await fetch('https://api.example.com/data');
          const jsonData = await response.json();
          setData(jsonData);
        };
        fetchData();
      }, []);
      return (
        <div>
          {data? (
            <div>
              <p>{data}</p>
            </div>
          ) : (
            <p>Loading...</p>
          )}
        </div>
      );
    };
    
    • 在这个例子中,useEffect中的函数在组件挂载时(因为依赖项数组[]为空,表示只在挂载时执行)调用fetchData函数来获取数据。获取到数据后,通过setData更新组件状态,组件会重新渲染以显示数据。如果fetchData函数是一个异步函数,需要在useEffect内部定义并调用,以确保正确的异步执行顺序。
  2. 依赖项数组的作用与使用
    • 依赖项数组用于控制useEffect函数的执行时机。如果依赖项数组中的值发生变化,useEffect中的函数会再次执行。
    • 例如,根据一个输入值来获取相关数据:
    import React, { useState, useEffect } from 'react';
    
    const InputDataFetchingComponent = () => {
      const [inputValue, setInputValue] = useState('');
      const [data, setData] = useState(null);
      useEffect(() => {
        const fetchData = async () => {
          const response = await fetch(`https://api.example.com/data?input=${inputValue}`);
          const jsonData = await response.json();
          setData(jsonData);
        };
        fetchData();
      }, [inputValue]);
      const handleInputChange = (e) => {
        setInputValue(e.target.value);
      };
      return (
        <div>
          <input type="text" value={inputValue} onChange={handleInputChange} />
          {data? (
            <div>
              <p>{data}</p>
            </div>
          ) : (
            <p>Loading...</p>
          )}
        </div>
      );
    };
    
    • 在这里,useEffect的依赖项数组包含inputValue。当inputValue发生变化时,useEffect中的fetchData函数会再次执行,获取新的数据并更新组件状态。

(三)useContext

  1. 基本概念与用法
    • useContext用于在函数组件中访问由Context.Provider提供的上下文(context)值。它接收一个Context对象作为参数,并返回该上下文对象的当前值。
    • 例如,创建一个主题上下文并在组件中使用:
    • 首先,创建主题上下文:
    import React from 'react';
    
    const ThemeContext = React.createContext('light');
    
    • 然后,在顶层组件中提供主题值:
    const App = () => {
      const [theme, setTheme] = useState('light');
      return (
        <ThemeContext.Provider value={theme}>
          <Header />
          <MainContent />
          <Footer />
        </ThemeContext.Provider>
      );
    };
    
    • 最后,在需要使用主题值的组件中通过useContext获取主题:
    const Button = () => {
      const theme = React.useContext(ThemeContext);
      return (
        <button className={`button - ${theme}`}>点击我</button>
      );
    };
    
    • 在这个例子中,useContext(ThemeContext)Button组件中获取了由App组件中ThemeContext.Provider提供的主题值,然后可以根据这个主题值来设置按钮的样式。

(四)useRef

  1. 基本概念与用法
    • useRef返回一个可变的ref对象,其current属性被初始化为传入的初始值。ref对象在组件的整个生命周期内保持不变,可以用于存储和访问DOM元素或任何可变的值,并且这个值在组件重新渲染时不会丢失。
    • 例如,访问和操作DOM元素:
    import React, { useRef } from 'react';
    
    const InputFocusComponent = () => {
      const inputRef = useRef(null);
      const handleClick = () => {
        inputRef.current.focus();
      };
      return (
        <div>
          <input ref={inputRef} type="text" />
          <button onClick={handleClick}>聚焦输入框</button>
        </div>
      );
    };
    
    • 在这个例子中,useRef(null)创建了一个ref对象inputRef,并通过input元素的ref属性将其与输入框关联。当按钮被点击时,handleClick函数通过inputRef.current.focus()访问输入框元素并使其获得焦点。
  2. useState的区别
    • useState用于管理组件状态,当状态更新时会触发组件重新渲染;而useRef主要用于存储一个持久的引用,其current属性的变化不会触发组件重新渲染。
    • 例如,比较一个使用useStateuseRef的计数器组件:
    • 使用useState
    import React, { useState } from 'react';
    
    const CounterWithState = () => {
      const [count, setCount] = useState(0);
      const handleClick = () => {
        setCount(count + 1);
      };
      return (
        <div>
          <p>Count: {count}</p>
          <button onClick={handleClick}>Increment</button>
        </div>
      );
    };
    
    • 使用useRef
    import React, { useRef } from 'react';
    
    const CounterWithRef = () => {
      const countRef = useRef(0);
      const handleClick = () => {
        countRef.current++;
      };
      return (
        <div>
          <p>Count: {countRef.current}</p>
          <button onClick={handleClick}>Increment</button>
        </div>
      );
    };
    
    • CounterWithState中,每次点击按钮,count状态更新,组件会重新渲染;而在CounterWithRef中,countRef.current的值改变时,组件不会重新渲染。

三、自定义Hooks

  1. 定义与规则
    • 自定义Hooks是一个以use开头的JavaScript函数,在函数内部可以使用其他React Hooks。自定义Hooks用于将组件中可复用的逻辑提取出来,使得代码更加模块化和易于维护。
    • 例如,创建一个自定义的useDebounce Hook来实现防抖功能:
    import React, { useState, useEffect } from 'react';
    
    const useDebounce = (value, delay) => {
      const [debouncedValue, setDebouncedValue] = useState(value);
      useEffect(() => {
        const timer = setTimeout(() => {
          setDebouncedValue(value);
        }, delay);
        return () => clearTimeout(timer);
      }, [value, delay]);
      return debouncedValue;
    };
    
    • 这个useDebounce Hook接收一个value和一个delay作为参数,返回经过防抖处理后的value。在useEffect中,通过定时器实现了防抖功能,当valuedelay发生变化时,会重新设置定时器。
  2. 使用场景与示例
    • 例如,在一个搜索框组件中使用useDebounce Hook来控制搜索请求的频率:
    import React from 'react';
    import useDebounce from './useDebounce';
    
    const SearchBox = () => {
      const [searchTerm, setSearchTerm] = useState('');
      const debouncedSearchTerm = useDebounce(searchTerm, 500);
      const handleSearch = () => {
        // 根据debouncedSearchTerm发送搜索请求,例如:
        console.log(`Searching for: ${debouncedSearchTerm}`);
      };
      const handleInputChange = (e) => {
        setSearchTerm(e.target.value);
      };
      return (
        <div>
          <input
            type="text"
            value={searchTerm}
            onChange={handleInputChange}
          />
          <button onClick={handleSearch}>Search</button>
        </div>
      );
    };
    
    • 在这个搜索框组件中,useDebounce Hook用于管理搜索词的状态。当用户在输入框中输入时,searchTerm状态会更新,但只有在用户停止输入500毫秒后,debouncedSearchTerm才会更新,然后点击搜索按钮时,会根据debouncedSearchTerm发送搜索请求,避免了频繁的搜索请求。

http://www.kler.cn/a/402343.html

相关文章:

  • 【数据结构与算法】合并链表、链表分割、链表回文结构
  • 刷题——字符串中的单词数(力扣)
  • CentOS环境上离线安装python3及相关包
  • 游戏引擎学习第22天
  • 软件/游戏提示:mfc42u.dll没有被指定在windows上运行如何解决?多种有效解决方法汇总分享
  • 内存不足引发C++程序闪退崩溃问题的分析与总结
  • C++ 多态相关
  • 【专题】中国企业出海洞察报告暨解码全球制胜之道报告汇总PDF洞察(附原数据表)
  • 小程序19-微信小程序的样式和组件介绍
  • React——useCallback
  • Kubernetes常用命令
  • 2025年软考报名时是什么时候?开考科目如何安排?
  • 使用ufw配置防火墙,允许特定范围IP访问
  • 解决 electron 打包后部分电脑报错 Error: Dynamic Symbol Retrieval Error: Win32 error 126
  • CI配置项,IT服务的关键要素
  • Vue3 + Vite 项目引入 Typescript
  • 应聘美容师要注意什么?博弈美业收银系统/管理系统/拓客系统分享建议
  • 【并发模式】Go 常见并发模式实现Runner、Pool、Work
  • 海外媒体软文发稿:打开全球传播的新窗口-大舍传媒
  • Android CCodec Codec2 (二一)InputBuffers
  • 【工控】线扫相机小结 第三篇
  • 项目进度计划表:详细的甘特图的制作步骤
  • Vulnhub靶场案例渗透[11]- Momentum2
  • Linux进阶:压缩、解压
  • 开源控件:Qt/C++自定义异形窗口和颜色选择器 【工程源码联系博主索要】
  • 【游戏开发】【Unity】基本的Unity概念