React Hooks完全指南

深入理解React Hooks的使用方法和最佳实践

React Hooks详解

React Hooks是React 16.8引入的新特性,它让你在不编写class的情况下使用state以及其他的React特性。本文将深入介绍Hooks的使用方法和最佳实践。

useState Hook

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import React, { useState } from 'react';

function Counter() {
    const [count, setCount] = useState(0);
    
    return (
        <div>
            <p>当前计数: {count}</p>
            <button onClick={() => setCount(count + 1)}>
                增加
            </button>
        </div>
    );
}

useEffect Hook

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import React, { useState, useEffect } from 'react';

function UserProfile({ userId }) {
    const [user, setUser] = useState(null);
    
    useEffect(() => {
        // 获取用户数据
        async function fetchUser() {
            const response = await fetch(`/api/users/${userId}`);
            const data = await response.json();
            setUser(data);
        }
        
        fetchUser();
    }, [userId]); // 仅在userId改变时重新获取
    
    if (!user) return 'Loading...';
    
    return (
        <div>
            <h1>{user.name}</h1>
            <p>{user.email}</p>
        </div>
    );
}

useContext Hook

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import React, { useContext } from 'react';

const ThemeContext = React.createContext('light');

function ThemedButton() {
    const theme = useContext(ThemeContext);
    
    return (
        <button style={{ background: theme === 'dark' ? '#000' : '#fff' }}>
            主题按钮
        </button>
    );
}

useReducer Hook

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import React, { useReducer } from 'react';

const initialState = { count: 0 };

function reducer(state, action) {
    switch (action.type) {
        case 'increment':
            return { count: state.count + 1 };
        case 'decrement':
            return { count: state.count - 1 };
        default:
            return state;
    }
}

function Counter() {
    const [state, dispatch] = useReducer(reducer, initialState);
    
    return (
        <div>
            计数: {state.count}
            <button onClick={() => dispatch({ type: 'increment' })}>+</button>
            <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
        </div>
    );
}

自定义Hook

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import { useState, useEffect } from 'react';

function useWindowSize() {
    const [size, setSize] = useState({
        width: window.innerWidth,
        height: window.innerHeight
    });
    
    useEffect(() => {
        const handleResize = () => {
            setSize({
                width: window.innerWidth,
                height: window.innerHeight
            });
        };
        
        window.addEventListener('resize', handleResize);
        return () => window.removeEventListener('resize', handleResize);
    }, []);
    
    return size;
}

// 使用自定义Hook
function ResponsiveComponent() {
    const size = useWindowSize();
    
    return (
        <div>
            窗口尺寸: {size.width} x {size.height}
        </div>
    );
}

useMemo和useCallback

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import React, { useMemo, useCallback } from 'react';

function ExpensiveComponent({ data, onItemClick }) {
    // 计算密集型操作使用useMemo
    const processedData = useMemo(() => {
        return data.map(item => item * 2);
    }, [data]);
    
    // 事件处理函数使用useCallback
    const handleClick = useCallback((id) => {
        onItemClick(id);
    }, [onItemClick]);
    
    return (
        <div>
            {processedData.map((item, index) => (
                <button key={index} onClick={() => handleClick(index)}>
                    {item}
                </button>
            ))}
        </div>
    );
}

useRef Hook

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import React, { useRef, useEffect } from 'react';

function AutoFocusInput() {
    const inputRef = useRef(null);
    
    useEffect(() => {
        // 组件挂载时自动聚焦
        inputRef.current.focus();
    }, []);
    
    return <input ref={inputRef} />;
}

Hooks使用规则

  1. 只在最顶层使用Hooks
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// 正确
function Component() {
    const [count, setCount] = useState(0);
    useEffect(() => {
        document.title = `Count: ${count}`;
    });
}

// 错误 - 条件语句中使用Hook
function Component() {
    if (condition) {
        const [count, setCount] = useState(0);
    }
}
  1. 只在React函数组件中使用Hooks
1
2
3
4
5
6
7
8
9
// 正确
function CustomComponent() {
    const [state, setState] = useState(null);
}

// 错误 - 普通函数中使用Hook
function normalFunction() {
    const [state, setState] = useState(null);
}

掌握这些React Hooks的使用方法,将帮助你写出更简洁、可维护的React组件。

使用绝夜之城强力驱动