Jupyter AI

33 React.js 中的自定义 Hooks

📅 发表日期: 2024年8月15日

分类: ⚛️React.js 入门

👁️阅读: --

在上一篇文章中,我们讨论了 React 中的常用 Hooks,例如 useStateuseEffectuseContext。这些 Hooks 为我们提供了状态管理和副作用处理的基本能力,但在实际开发中,我们常常会面临一些特定的需求,这时就可以考虑创建自定义 Hooks。自定义 Hooks 允许我们将组件逻辑提取为可重用的函数,为代码的结构和可维护性提供了很大的帮助。

什么是自定义 Hooks?

自定义 Hooks 是一个普通的 JavaScript 函数,其名称以 use 开头,并且可以调用其他的 Hooks。它们允许我们将组件逻辑提取成独立的函数,以便在多个组件之间共享。

如何创建自定义 Hooks?

创建自定义 Hooks 并不复杂。以下是一个简单的示例,展示如何创建一个用于获取窗口尺寸的自定义 Hook。

import { useState, useEffect } from 'react';

function useWindowSize() {
    const [windowSize, setWindowSize] = useState({
        width: window.innerWidth,
        height: window.innerHeight,
    });

    useEffect(() => {
        const handleResize = () => {
            setWindowSize({
                width: window.innerWidth,
                height: window.innerHeight,
            });
        };

        window.addEventListener('resize', handleResize);
        
        // 清理事件监听器
        return () => window.removeEventListener('resize', handleResize);
    }, []);

    return windowSize;
}

使用自定义 Hooks

有了 useWindowSize 自定义 Hook 后,我们可以在任何组件中使用它,例如:

import React from 'react';
import useWindowSize from './useWindowSize';

function DisplaySize() {
    const { width, height } = useWindowSize();

    return (
        <div>
            <h1>窗口尺寸</h1>
            <p>宽度: {width}px</p>
            <p>高度: {height}px</p>
        </div>
    );
}

在上面的例子中,当窗口大小改变时,DisplaySize 组件会自动更新显示的宽度和高度。

进阶自定义 Hooks 的使用

接受参数的自定义 Hooks

其实,自定义 Hooks 还可以接受参数,以便于我们更加灵活地使用。例如,创建一个 countdown 自定义 Hook:

import { useState, useEffect } from 'react';

function useCountdown(initialCount) {
    const [count, setCount] = useState(initialCount);

    useEffect(() => {
        if (count === 0) return;

        const interval = setInterval(() => {
            setCount(prevCount => prevCount - 1);
        }, 1000);

        return () => clearInterval(interval);
    }, [count]);

    return count;
}

使用这个 countdown Hook 的组件:

import React from 'react';
import useCountdown from './useCountdown';

function CountdownTimer() {
    const count = useCountdown(10); // 从 10 开始倒计时

    return (
        <div>
            <h1>倒计时: {count}</h1>
        </div>
    );
}

改善逻辑重用

使用自定义 Hooks 的另一个重要优势是能够减少逻辑的重复。如果有多个组件需要实现相同的功能,比如表单输入的控制、数据获取等场景,就可以将其逻辑提取出来,形成自定义 Hooks。例如,我们可以创建一个用于处理表单输入的自定义 Hook useFormInput

import { useState } from 'react';

function useFormInput(initialValue) {
    const [value, setValue] = useState(initialValue);
    
    const handleChange = (event) => {
        setValue(event.target.value);
    };

    return {
        value,
        onChange: handleChange,
    };
}

使用这个 useFormInput Hook 的组件示例:

import React from 'react';
import useFormInput from './useFormInput';

function MyForm() {
    const name = useFormInput('');
    const email = useFormInput('');

    const handleSubmit = (event) => {
        event.preventDefault();
        console.log('Name:', name.value);
        console.log('Email:', email.value);
    };

    return (
        <form onSubmit={handleSubmit}>
            <div>
                <label>
                    姓名:
                    <input type="text" {...name} />
                </label>
            </div>
            <div>
                <label>
                    邮箱:
                    <input type="email" {...email} />
                </label>
            </div>
            <button type="submit">提交</button>
        </form>
    );
}

结束语

通过使用自定义 Hooks,我们可以使组件的逻辑更加清晰、可重用性更高。在下一篇文章中,我们将结合实战项目,进行项目需求分析,帮助您更好地将所学的知识应用到实际的开发中。希望您能够继续关注此次 React.js 从零教程的系列,期待与您在实战中相见!

⚛️React.js 入门 (滚动鼠标查看)