react18【系列实用教程】Hooks (useState,useReducer,useRef,useEffect,useContext,useMemo,useCallback,自定义 Hook )

简介: react18【系列实用教程】Hooks (useState,useReducer,useRef,useEffect,useContext,useMemo,useCallback,自定义 Hook )

Hook 是什么?

React 中,以“use”开头的函数都被称为 Hook。

Hook 是实现特殊功能的函数,只在 React 渲染时有效,只能在组件或自定义 Hook 的最顶层调用。

React 内置了很多 Hook ,你也可以自定义 Hook。

Hook 的使用规范

1.只能在 react 函数组件和自定义 Hook 中使用

2.只能在顶层使用,不能在判断(如 if 语句)/ 循环(如 for 语句)中使用

因为 Hooks 严重依赖于调用顺序,在组件挂载(render)和更新(re-render)时,Hooks 的调用顺序必须保持一致,若在判断/循环语句中使用,则可能引发 Hooks 的调用顺序发生改变,导致 Hooks 内的逻辑错乱(如响应式变量的值赋值给了其他变量)。

Hook 实现组件逻辑复用的好处

  • 完全符合 Hooks 原有规则,易理解记忆
  • 变量作用域明确
  • 不会产生组件嵌套

其他方式实现组件逻辑复用的缺陷

Mixins(已废弃)的缺陷

与 vue 相同

  • 变量作用域来源不清
  • 属性重名
  • Mixins 引入过多会导致顺序冲突

高阶组件 HOC 的缺陷

高阶组件 HOC 是 react 的 class 组件实现组件逻辑复用的一种方式

  • 组件层级嵌套过多,不易渲染,不易调试
  • HOC 会劫持 props,必须严格规范,容易出现疏漏

Render Prop 的缺陷

Render Prop 是 react 的 class 组件实现组件逻辑复用的另一种方式

  • 学习成本高,不易理解
  • 只能传递纯函数,而默认情况下纯函数功能有限

React 的内置 Hook

useState

详见 https://blog.csdn.net/weixin_41192489/article/details/138664118


useReducer

详见 https://blog.csdn.net/weixin_41192489/article/details/138863860


useRef

详见 https://blog.csdn.net/weixin_41192489/article/details/138952934


useEffect

详见 https://blog.csdn.net/weixin_41192489/article/details/138706946


useContext

详见 https://blog.csdn.net/weixin_41192489/article/details/138700487


useMemo

详见 https://blog.csdn.net/weixin_41192489/article/details/138909376


useCallback

详见 https://blog.csdn.net/weixin_41192489/article/details/138911123

自定义 Hook

即根据自己的业务需要编写use开头的函数,实现逻辑封装和复用。

自定义 Hook 的步骤

  1. 新建文件 myHooks.js,存放所有自定义的 hook
  2. 将可复用的逻辑封装成use开头的函数,以对象或数组的数据格式 return 组件中需要用到的变量和函数
  3. 对外导出自定义的 hook
  4. 在目标组件中导入自定义的 hook
  5. 通过对象/数组解构赋值(与自定义 hook 中return 的数据格式对应),使用自定义的 hook

范例1 - 切换显示隐藏 useToggle

myHooks.js

import { useState } from "react";

// 切换显示隐藏
export const useToggle = (initValue) => {
  const [show, setShow] = useState(initValue);

  function toggleShow() {
    setShow(!show);
  }

  return [show, toggleShow];
};

index.jsx

import { useToggle } from "./myHooks.js";

function Demo() {
  const [showTitle, toggleShowTitle] = useToggle(true);
  const [showContent, toggleShowContent] = useToggle(false);

  return (
    <>
      {showTitle && <h1>标题</h1>}
      <button onClick={toggleShowTitle}>显示/隐藏标题</button>

      <div>
        {showContent && <p>段落</p>}
        <button onClick={toggleShowContent}>显示/隐藏内容</button>
      </div>
    </>
  );
}

export default Demo;

范例2 - 组件挂载时请求接口数据 useGetInitData

myHooks.js

import { useState, useEffect } from "react";
import axios from "axios";

// 访问接口
export const useGetInitData = (url) => {
  const [data, setData] = useState([]);
  useEffect(() => {
    async function getData() {
      const res = await axios.get(url);
      setData(res.data);
    }
    getData();
  }, []);

  return [data, setData];
};

index.jsx

import { useGetInitData } from "./myHooks.js";

function Demo() {
  const [list, setList] = useGetInitData("http://localhost:3000/dataList");

  function clearList() {
    setList([]);
  }

  return (
    <>
      {list.map((item) => (
        <div key={item.id}>{item.title}</div>
      ))}
      <button onClick={clearList}>清空</button>
    </>
  );
}

export default Demo;

范例3 - url 改变时请求接口数据 useAxios

useAxios.js

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

// 封装 axios 发送网络请求的自定义 Hook
function useAxios(url) {
    const [loading, setLoading] = useState(false)
    const [data, setData] = useState()
    const [error, setError] = useState()

    useEffect(() => {
        // 利用 axios 发送网络请求
        setLoading(true)
        axios.get(url) // 发送一个 get 请求
            .then(res => setData(res))
            .catch(err => setError(err))
            .finally(() => setLoading(false))
    }, [url])

    return [loading, data, error]
}

export default useAxios

使用

import useAxios from './useAxios'
 
 const url = 'http://localhost:3000/'
 // 数组解构
 const [loading, data, error] = useAxios(url)

 if (loading) return <div>loading...</div>

 return error
     ? <div>{JSON.stringify(error)}</div>
     : <div>{JSON.stringify(data)}</div>

范例4 - 实时获取鼠标坐标 useAxios

useMousePosition.js

import { useState, useEffect } from 'react'

function useMousePosition() {
    const [x, setX] = useState(0)
    const [y, setY] = useState(0)

    useEffect(() => {
        function mouseMoveHandler(event) {
            setX(event.clientX)
            setY(event.clientY)
        }

        // 绑定事件
        document.body.addEventListener('mousemove', mouseMoveHandler)

        // 解绑事件
        return () => document.body.removeEventListener('mousemove', mouseMoveHandler)
    }, [])

    return [x, y]
}

export default useMousePosition

使用

import useMousePosition from './useMousePosition'
 
const [x, y] = useMousePosition()
return <div>
    <p>鼠标位置 {x} {y}</p>
</div>

目录
相关文章
|
10天前
|
前端开发 JavaScript
深入探索React Hooks:从useState到useEffect
深入探索React Hooks:从useState到useEffect
|
20天前
|
前端开发 JavaScript 开发者
“揭秘React Hooks的神秘面纱:如何掌握这些改变游戏规则的超能力以打造无敌前端应用”
【10月更文挑战第25天】React Hooks 自 2018 年推出以来,已成为 React 功能组件的重要组成部分。本文全面解析了 React Hooks 的核心概念,包括 `useState` 和 `useEffect` 的使用方法,并提供了最佳实践,如避免过度使用 Hooks、保持 Hooks 调用顺序一致、使用 `useReducer` 管理复杂状态逻辑、自定义 Hooks 封装复用逻辑等,帮助开发者更高效地使用 Hooks,构建健壮且易于维护的 React 应用。
28 2
|
24天前
|
前端开发 开发者
React 提供的其他重要 Hooks
【10月更文挑战第20天】React 提供了一系列强大的 Hooks,除了 `useRef` 之外,还有许多其他重要的 Hooks,它们共同构成了函数式组件开发的基础。
35 6
|
1月前
|
前端开发 JavaScript 开发者
React Hooks
10月更文挑战第13天
34 1
|
1月前
|
前端开发 JavaScript 开发者
深入理解React Hooks:提升前端开发效率的关键
【10月更文挑战第5天】深入理解React Hooks:提升前端开发效率的关键
|
13天前
|
前端开发 JavaScript 开发者
颠覆传统:React框架如何引领前端开发的革命性变革
【10月更文挑战第32天】本文以问答形式探讨了React框架的特性和应用。React是一款由Facebook推出的JavaScript库,以其虚拟DOM机制和组件化设计,成为构建高性能单页面应用的理想选择。文章介绍了如何开始一个React项目、组件化思想的体现、性能优化方法、表单处理及路由实现等内容,帮助开发者更好地理解和使用React。
41 9
|
1月前
|
前端开发
深入解析React Hooks:构建高效且可维护的前端应用
本文将带你走进React Hooks的世界,探索这一革新特性如何改变我们构建React组件的方式。通过分析Hooks的核心概念、使用方法和最佳实践,文章旨在帮助你充分利用Hooks来提高开发效率,编写更简洁、更可维护的前端代码。我们将通过实际代码示例,深入了解useState、useEffect等常用Hooks的内部工作原理,并探讨如何自定义Hooks以复用逻辑。
|
1月前
|
前端开发 JavaScript API
探索React Hooks:前端开发的革命性工具
【10月更文挑战第5天】探索React Hooks:前端开发的革命性工具
|
1月前
|
前端开发 数据管理 编译器
引领前端未来:React 19的重大更新与实战指南🚀
React 19 即将发布,带来一系列革命性的新功能,旨在简化开发过程并显著提升性能。本文介绍了 React 19 的核心功能,如自动优化重新渲染的 React 编译器、加速初始加载的服务器组件、简化表单处理的 Actions、无缝集成的 Web 组件,以及文档元数据的直接管理。这些新功能通过自动化、优化和增强用户体验,帮助开发者构建更高效的 Web 应用程序。
97 1
引领前端未来:React 19的重大更新与实战指南🚀
|
18天前
|
前端开发 JavaScript Android开发
前端框架趋势:React Native在跨平台开发中的优势与挑战
【10月更文挑战第27天】React Native 是跨平台开发领域的佼佼者,凭借其独特的跨平台能力和高效的开发体验,成为许多开发者的首选。本文探讨了 React Native 的优势与挑战,包括跨平台开发能力、原生组件渲染、性能优化及调试复杂性等问题,并通过代码示例展示了其实际应用。
45 2