标签: React

  • 为何React的Hook名字前缀都是use ?

    在 React 中,Hook 的名字前缀为 use 是为了遵循一套约定和规则,这些规则帮助开发者理解和使用 Hook。具体原因如下:

    • 标识性:以 use 开头的命名约定使得开发者能够快速识别出哪些函数是 Hook。这种命名方式在代码中提供了清晰的语义,表明这些函数是用于管理状态或副作用的。
    • 规则遵循:React 的 Hook 有一些特定的使用规则,例如:
    • 只能在函数组件或自定义 Hook 中调用。
    • 不能在循环、条件或嵌套函数中调用。 通过强制使用 use 前缀,React 团队能够在开发过程中进行一些静态分析,帮助开发者遵循这些规则。
    • 一致性:使用 use 前缀为所有 Hook 提供了一种一致的命名方式。这种一致性使得代码更易于阅读和维护,尤其是在大型项目中。
    • 社区约定:随着 React 的发展,社区逐渐接受了这一命名约定。遵循这一约定可以使得代码更具可读性,并且更容易被其他开发者理解。

    总之,use 前缀不仅是一个约定,更是 React 设计的一部分,旨在提高代码的可读性和可维护性,同时帮助开发者遵循 Hook 的使用规则。

  • 使用 React Hook 实现庆祝效果的简单指南

    在这篇文章中,我们将深入探讨一个简单而有趣的 React Hook:useConfetti。这个 Hook 的主要功能是在特定状态下触发庆祝效果,使用了 canvas-confetti 库来实现五彩纸屑的动画效果。让我们逐步分析这个文件的内容,并了解它是如何工作的。

    文件结构

    我们来看一下 useConfetti.ts 文件的结构:

    import { CONFETTI_DEFAULTS } from '@/constants'
    import confetti from 'canvas-confetti'
    import { useEffect } from 'react'
    
    export function useConfetti(state: boolean) {
      useEffect(() => {
        let leftConfettiTimer: number | undefined
        let rightConfettiTimer: number | undefined
        if (state) {
          leftConfettiTimer = window.setTimeout(() => {
            confetti({
              ...CONFETTI_DEFAULTS,
              particleCount: 50,
              angle: 60,
              spread: 100,
              origin: { x: 0 },
            })
          }, 250)
          rightConfettiTimer = window.setTimeout(() => {
            confetti({
              ...CONFETTI_DEFAULTS,
              particleCount: 50,
              angle: 120,
              spread: 100,
              origin: { x: 1 },
            })
          }, 400)
        }
        return () => {
          window.clearTimeout(leftConfettiTimer)
          window.clearTimeout(rightConfettiTimer)
        }
      }, [state])
    }

    代码解析

    1. 导入依赖

    首先,我们导入了几个必要的模块:

    • CONFETTI_DEFAULTS:这是一个常量,包含了五彩纸屑的默认配置。
    • canvas-confetti:这是一个用于生成五彩纸屑效果的库。
    • useEffect:这是 React 的一个 Hook,用于处理副作用。

    2. 定义 useConfetti Hook

    useConfetti 是一个接受布尔值 state 的函数。当 statetrue 时,它会触发五彩纸屑效果。

    3. 使用 useEffect

    useEffect 中,我们设置了两个定时器:

    • leftConfettiTimer:在 250 毫秒后,从左侧发射五彩纸屑。
    • rightConfettiTimer:在 400 毫秒后,从右侧发射五彩纸屑。

    这两个定时器使用 window.setTimeout 来延迟执行 confetti 函数,生成五彩纸屑效果。

    4. 清理定时器

    useEffect 的返回函数中,我们使用 window.clearTimeout 来清理定时器,确保在组件卸载时不会继续执行未完成的定时器。

    5. 依赖数组

    useEffect 的依赖数组包含 state,这意味着每当 state 发生变化时,useEffect 都会重新执行。

    如何使用 useConfetti

    要在你的组件中使用 useConfetti,你只需传入一个布尔值来控制庆祝效果的触发。例如:

    import React, { useState } from 'react';
    import { useConfetti } from './hooks/useConfetti';
    
    const CelebrationComponent = () => {
      const [celebrate, setCelebrate] = useState(false);
      useConfetti(celebrate);
    
      return (
        <div>
          <button onClick={() => setCelebrate(true)}>庆祝!</button>
        </div>
      );
    };
    
    export default CelebrationComponent;

    在这个示例中,当用户点击按钮时,celebrate 状态将被设置为 true,从而触发五彩纸屑效果。

    总结

    useConfetti 是一个简单而有效的 React Hook,可以为你的应用添加一些有趣的视觉效果。通过使用 canvas-confetti 库和 React 的 useEffect Hook,我们能够轻松地实现这一功能。希望这篇文章能帮助你更好地理解 React Hook 的使用,并激发你在项目中实现更多有趣的效果!

  • React Hook 简介

    React Hook 是 React 16.8 版本引入的一种功能,允许开发者在函数组件中使用状态(state)和其他 React 特性,而不需要编写类组件。Hooks 提供了一种更简洁和灵活的方式来管理组件的生命周期和状态。

    常见的 React Hooks

    • useState
    • 用于在函数组件中添加状态。
    • 语法示例:
         const [count, setCount] = useState(0);
    • useEffect
    • 用于处理副作用,例如数据获取、订阅或手动操作 DOM。
    • 语法示例:
         useEffect(() => {
           // 代码逻辑
           return () => {
             // 清理逻辑
           };
         }, [dependencies]);
    • useContext
    • 用于在组件树中共享状态,而不需要通过 props 逐层传递。
    • 语法示例:
         const value = useContext(MyContext);
    • useReducer
    • 用于在函数组件中管理复杂的状态逻辑,类似于 Redux 的 reducer。
    • 语法示例:
         const [state, dispatch] = useReducer(reducer, initialState);
    • 自定义 Hooks
    • 开发者可以创建自己的 Hooks,以封装和重用逻辑。
    • 语法示例:
         function useMyCustomHook() {
           // 自定义逻辑
         }

    优势

    • 简化代码:Hooks 使得函数组件更简洁,减少了类组件的复杂性。
    • 逻辑复用:通过自定义 Hooks,可以轻松复用状态逻辑。
    • 更好的组合性:Hooks 允许将状态和副作用逻辑组合在一起,提升了代码的可读性和可维护性。

    总之,React Hooks 是一种强大的工具,使得在函数组件中管理状态和副作用变得更加简单和灵活。


    useReducer 是 React 提供的一个 Hook,用于在函数组件中管理复杂的状态逻辑。它的工作原理类似于 Redux 中的 reducer,允许你通过 dispatching actions 来更新状态。useReducer 特别适合于需要管理多个子值或复杂状态逻辑的场景。

    基本用法

    useReducer 接受三个参数:

    1. reducer:一个函数,接收当前状态和一个 action,并返回新的状态。
    2. initialState:初始状态。
    3. init(可选):一个函数,用于延迟初始化状态。

    示例

    下面是一个使用 useReducer 的示例,展示了如何管理一个计数器的状态。

    import React, { useReducer } from 'react';
    
    // 定义初始状态
    const initialState = { count: 0 };
    
    // 定义 reducer 函数
    function reducer(state, action) {
      switch (action.type) {
        case 'increment':
          return { count: state.count + 1 };
        case 'decrement':
          return { count: state.count - 1 };
        case 'reset':
          return initialState;
        default:
          throw new Error();
      }
    }
    
    // 创建计数器组件
    function Counter() {
      // 使用 useReducer
      const [state, dispatch] = useReducer(reducer, initialState);
    
      return (
        <div>
          <p>Count: {state.count}</p>
          <button onClick={() => dispatch({ type: 'increment' })}>Increment</button>
          <button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button>
          <button onClick={() => dispatch({ type: 'reset' })}>Reset</button>
        </div>
      );
    }
    
    export default Counter;

    代码解析

    • 初始状态
    • initialState 是一个对象,包含一个 count 属性,初始值为 0。
    • reducer 函数
    • reducer 函数接收当前状态和一个 action,根据 action 的类型返回新的状态。
    • 支持三种 action:
      • increment:将 count 增加 1。
      • decrement:将 count 减少 1。
      • reset:将 count 重置为初始状态。
    • 使用 useReducer
    • Counter 组件中,调用 useReducer,传入 reducer 函数和 initialState,返回当前状态和 dispatch 函数。
    • dispatch 函数用于发送 action,更新状态。
    • 渲染 UI
    • 组件渲染当前的 count 值,并提供三个按钮来触发不同的 action。

    优势

    • 状态管理useReducer 使得管理复杂状态变得简单,特别是在状态依赖于多个子值时。
    • 可读性:通过将状态更新逻辑集中在 reducer 函数中,代码的可读性和可维护性得以提高。
    • 调试:使用 reducer 的模式使得调试状态变化变得更加容易,因为所有的状态变化都通过 action 进行。

    总之,useReducer 是一个强大的工具,适用于需要复杂状态管理的 React 组件。


    useEffect 是 React 中的一个 Hook,用于处理副作用(side effects)。副作用可以是数据获取、订阅、手动操作 DOM、设置定时器等。useEffect 允许你在函数组件中执行这些操作,并在组件的生命周期中进行清理。

    基本用法

    useEffect 接受两个参数:

    1. effect:一个函数,包含副作用的逻辑。
    2. dependencies(可选):一个数组,指定 effect 依赖的变量。当这些变量发生变化时,effect 会重新执行。

    示例

    下面是一个使用 useEffect 的示例,展示了如何在组件加载时获取数据,并在组件卸载时清理定时器。

    import React, { useState, useEffect } from 'react';
    
    function DataFetcher() {
      const [data, setData] = useState(null);
      const [loading, setLoading] = useState(true);
    
      useEffect(() => {
        // 定义一个异步函数来获取数据
        const fetchData = async () => {
          try {
            const response = await fetch('https://api.example.com/data');
            const result = await response.json();
            setData(result);
          } catch (error) {
            console.error('Error fetching data:', error);
          } finally {
            setLoading(false);
          }
        };
    
        // 调用异步函数
        fetchData();
    
        // 清理函数(可选)
        return () => {
          console.log('Cleanup if necessary');
        };
      }, []); // 空数组表示只在组件挂载和卸载时执行
    
      if (loading) {
        return <div>Loading...</div>;
      }
    
      return (
        <div>
          <h1>Fetched Data</h1>
          <pre>{JSON.stringify(data, null, 2)}</pre>
        </div>
      );
    }
    
    export default DataFetcher;

    代码解析

    • 状态管理
    • 使用 useState 创建两个状态变量:data 用于存储获取的数据,loading 用于指示数据是否正在加载。
    • 使用 useEffect
    • useEffect 中定义一个异步函数 fetchData,用于从 API 获取数据。
    • 使用 fetch 方法发送请求,并将响应数据解析为 JSON 格式。
    • 使用 setData 更新状态,将获取的数据存储在 data 中。
    • 使用 setLoading(false) 更新 loading 状态,表示数据加载完成。
    • catch 块中处理可能的错误,并在控制台输出错误信息。
    • 清理函数
    • useEffect 可以返回一个清理函数,用于在组件卸载时执行清理操作。在这个示例中,清理函数只是输出一条日志,实际应用中可以用于清理订阅、取消请求等。
    • 依赖数组
    • 传入空数组 [] 作为依赖项,表示该 effect 只在组件挂载时执行一次,并在卸载时执行清理函数。
    • 渲染 UI
    • 如果 loadingtrue,则显示加载状态;否则,显示获取到的数据。

    优势

    • 控制副作用useEffect 使得在函数组件中处理副作用变得简单和直观。
    • 清理机制:可以在组件卸载时清理副作用,避免内存泄漏。
    • 依赖管理:通过依赖数组,可以精确控制 effect 的执行时机,避免不必要的重新执行。

    总之,useEffect 是一个强大的工具,适用于处理各种副作用,提升了函数组件的功能性和灵活性。

  • 【项目解析】qwerty-learner

    qwerty-learner

    为键盘工作者设计的单词记忆与英语肌肉记忆锻炼软件 / Words learning and English muscle memory training software designed for keyboard workers

    在 React 中,”Hooks” 是一种允许你在函数组件中使用状态和其他 React 特性(如生命周期方法)的功能。Hooks 使得函数组件能够拥有类组件的能力,而不需要使用类。以下是一些常见的 Hooks 概念:

    • 内置 Hooks
    • useState:用于在函数组件中添加状态。
    • useEffect:用于处理副作用,例如数据获取、订阅或手动操作 DOM。
    • useContext:用于在组件树中共享状态,而不需要通过 props 逐层传递。
    • 自定义 Hooks
    • 开发者可以创建自己的 Hooks,以封装和重用逻辑。例如,useIntersectionObserver 是一个自定义 Hook,用于处理元素的可见性检测。
    • Hooks 的优势
    • 简化代码:Hooks 使得状态管理和副作用处理变得更加简单和直观。
    • 逻辑复用:自定义 Hooks 允许开发者将逻辑提取到可重用的函数中,避免代码重复。
    • 更好的组织:Hooks 使得组件的逻辑更加清晰,便于理解和维护。

    因此,”Hooks” 目录通常包含与 Hooks 相关的代码,可能包括自定义 Hooks 的实现,帮助开发者在 React 应用中更有效地管理状态和副作用。


    src/hooks/useIntersectionObserver.ts 文件中,定义了一个自定义 Hook,名为 useIntersectionObserver。这个 Hook 的主要作用是监测一个 DOM 元素的可见性状态,具体功能如下:

    • 监测可见性
    • 该 Hook 使用 Intersection Observer API 来检测指定的 DOM 元素是否在视口中可见。它会返回一个 IntersectionObserverEntry 对象,包含有关元素可见性的信息。
    • 参数配置
    • Hook 接受一个 elementRef(指向要监测的 DOM 元素的引用)和一个配置对象(包括 thresholdrootrootMarginfreezeOnceVisible)。这些参数允许开发者自定义监测的行为:
      • threshold:表示多少比例的目标元素可见时触发回调。
      • root:可选的根元素,默认为 null,表示视口。
      • rootMargin:根元素的边距,用于调整可见性检测的边界。
      • freezeOnceVisible:如果设置为 true,一旦元素可见,Hook 将停止更新状态。
    • 状态管理
    • 使用 useState 来存储当前的可见性状态(entry),并在元素的可见性发生变化时更新该状态。
    • 副作用处理
    • 使用 useEffect 来设置和清理 Intersection Observer。当组件挂载时,开始观察指定的 DOM 元素;当组件卸载时,停止观察。
    • 返回值
    • Hook 返回当前的 IntersectionObserverEntry,使得调用该 Hook 的组件可以根据元素的可见性状态进行相应的渲染或逻辑处理。

    总之,useIntersectionObserver Hook 提供了一种简洁的方式来监测 DOM 元素的可见性,适用于需要根据元素在视口中的状态进行动态渲染或行为的场景。


人生梦想 - 关注前沿的计算机技术 acejoy.com