前端高级工程师(大前端) | 已完结

41 阅读5分钟

6b49092bly4hcudtez42jj20xc0m8gpz.jpg

React Hooks 设计哲学与自定义Hooks最佳实践

我将为您创建一个关于React Hooks设计哲学与自定义Hooks最佳实践的交互式教程页面。这个页面将展示Hooks的核心概念、设计原则以及实际应用示例。

设计思路

这个页面需要包含以下核心部分:

  • React Hooks的设计哲学介绍
  • 常用内置Hooks的详细说明
  • 自定义Hooks的最佳实践指南
  • 交互式示例演示Hooks的实际应用
  • 响应式设计确保在各种设备上良好显示

下面是完整的实现代码:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>React Hooks 设计哲学与自定义Hooks最佳实践</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        }
        
        body {
            background-color: #f5f7fa;
            color: #333;
            line-height: 1.6;
        }
        
        .container {
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
        }
        
        header {
            background: linear-gradient(135deg, #61dafb, #2196f3);
            color: white;
            padding: 60px 20px;
            text-align: center;
            border-radius: 10px;
            margin-bottom: 30px;
            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
        }
        
        header h1 {
            font-size: 2.8rem;
            margin-bottom: 15px;
        }
        
        header p {
            font-size: 1.2rem;
            max-width: 800px;
            margin: 0 auto;
        }
        
        .section {
            background-color: white;
            padding: 30px;
            border-radius: 10px;
            margin-bottom: 30px;
            box-shadow: 0 4px 10px rgba(0, 0, 0, 0.05);
        }
        
        .section-title {
            color: #2196f3;
            border-left: 5px solid #61dafb;
            padding-left: 15px;
            margin: 25px 0;
        }
        
        .cards-container {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
            gap: 20px;
            margin: 30px 0;
        }
        
        .card {
            background: white;
            border-radius: 8px;
            padding: 20px;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.05);
            transition: transform 0.3s ease;
            border-top: 4px solid #61dafb;
        }
        
        .card:hover {
            transform: translateY(-5px);
        }
        
        .card i {
            font-size: 2.5rem;
            color: #61dafb;
            margin-bottom: 15px;
        }
        
        .card h3 {
            color: #2196f3;
            margin-bottom: 10px;
        }
        
        .code-block {
            background-color: #282c34;
            color: #abb2bf;
            padding: 15px;
            border-radius: 5px;
            margin: 15px 0;
            overflow-x: auto;
            font-family: 'Courier New', monospace;
            font-size: 0.9rem;
        }
        
        .code-keyword {
            color: #c678dd;
        }
        
        .code-function {
            color: #61afef;
        }
        
        .code-string {
            color: #98c379;
        }
        
        .code-comment {
            color: #5c6370;
        }
        
        .code-jsx {
            color: #d19a66;
        }
        
        .demo-area {
            border: 1px solid #e1e5e9;
            border-radius: 8px;
            padding: 20px;
            margin: 20px 0;
            background-color: #f8f9fa;
        }
        
        .demo-title {
            font-size: 1.2rem;
            color: #2196f3;
            margin-bottom: 15px;
            display: flex;
            align-items: center;
        }
        
        .demo-title i {
            margin-right: 10px;
        }
        
        .tabs {
            display: flex;
            border-bottom: 1px solid #e1e5e9;
            margin-bottom: 15px;
        }
        
        .tab {
            padding: 10px 20px;
            cursor: pointer;
            border-bottom: 3px solid transparent;
        }
        
        .tab.active {
            border-bottom: 3px solid #61dafb;
            color: #2196f3;
            font-weight: bold;
        }
        
        .tab-content {
            display: none;
        }
        
        .tab-content.active {
            display: block;
        }
        
        .hook-demo {
            background-color: white;
            padding: 20px;
            border-radius: 8px;
            margin: 20px 0;
            box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05);
        }
        
        .demo-controls {
            display: flex;
            gap: 10px;
            margin: 15px 0;
        }
        
        button {
            background-color: #61dafb;
            color: white;
            border: none;
            padding: 8px 15px;
            border-radius: 4px;
            cursor: pointer;
            font-weight: bold;
            transition: background-color 0.3s;
        }
        
        button:hover {
            background-color: #2196f3;
        }
        
        .counter-display {
            font-size: 1.5rem;
            font-weight: bold;
            color: #2196f3;
            margin: 10px 0;
        }
        
        .best-practices {
            background-color: #e3f2fd;
            padding: 20px;
            border-radius: 8px;
            margin: 20px 0;
            border-left: 4px solid #2196f3;
        }
        
        .practice-item {
            margin-bottom: 15px;
            display: flex;
            align-items: flex-start;
        }
        
        .practice-icon {
            color: #2196f3;
            margin-right: 10px;
            margin-top: 3px;
        }
        
        footer {
            text-align: center;
            padding: 20px;
            color: #7f8c8d;
            font-size: 0.9rem;
        }
        
        @media (max-width: 768px) {
            header h1 {
                font-size: 2rem;
            }
            
            .cards-container {
                grid-template-columns: 1fr;
            }
            
            .demo-controls {
                flex-direction: column;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <header>
            <h1>React Hooks 设计哲学与最佳实践</h1>
            <p>深入理解React Hooks的设计思想,掌握自定义Hooks的开发技巧</p>
        </header>
        
        <section class="section">
            <h2 class="section-title">React Hooks 设计哲学</h2>
            <p>React Hooks 是 React 16.8 引入的革命性特性,它允许我们在函数组件中使用状态和其他React特性。Hooks的设计基于以下几个核心原则:</p>
            
            <div class="cards-container">
                <div class="card">
                    <i class="fas fa-code"></i>
                    <h3>逻辑复用</h3>
                    <p>Hooks 使得状态逻辑的复用变得更加简单,无需使用高阶组件或render props等复杂模式。</p>
                </div>
                
                <div class="card">
                    <i class="fas fa-project-diagram"></i>
                    <h3>关注点分离</h3>
                    <p>通过自定义Hooks,可以将组件拆分为更小的函数,每个函数负责一个独立的关注点。</p>
                </div>
                
                <div class="card">
                    <i class="fas fa-cube"></i>
                    <h3>函数式思维</h3>
                    <p>Hooks 鼓励使用函数式编程范式,使代码更简洁、可预测和易于测试。</p>
                </div>
            </div>
            
            <div class="code-block">
                <span class="code-comment">// 类组件 vs 函数组件 + Hooks</span><br>
                <span class="code-comment">// 类组件方式</span><br>
                <span class="code-keyword">class</span> Example <span class="code-keyword">extends</span> React.Component {<br>
                &nbsp;&nbsp;constructor(props) {<br>
                &nbsp;&nbsp;&nbsp;&nbsp;<span class="code-keyword">super</span>(props);<br>
                &nbsp;&nbsp;&nbsp;&nbsp;<span class="code-keyword">this</span>.state = { count: <span class="code-keyword">0</span> };<br>
                &nbsp;&nbsp;}<br>
                &nbsp;&nbsp;render() {<br>
                &nbsp;&nbsp;&nbsp;&nbsp;<span class="code-keyword">return</span> (<br>
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="code-jsx">&lt;div&gt;</span><br>
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="code-jsx">&lt;p&gt;</span>You clicked {<span class="code-keyword">this</span>.state.count} times<span class="code-jsx">&lt;/p&gt;</span><br>
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="code-jsx">&lt;button onClick=</span>{() => <span class="code-keyword">this</span>.setState({ count: <span class="code-keyword">this</span>.state.count + <span class="code-keyword">1</span> })}<span class="code-jsx">&gt;</span><br>
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Click me<br>
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="code-jsx">&lt;/button&gt;</span><br>
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="code-jsx">&lt;/div&gt;</span><br>
                &nbsp;&nbsp;&nbsp;&nbsp;);<br>
                &nbsp;&nbsp;}<br>
                }<br>
                <br>
                <span class="code-comment">// 函数组件 + Hooks 方式</span><br>
                <span class="code-keyword">function</span> <span class="code-function">Example</span>() {<br>
                &nbsp;&nbsp;<span class="code-keyword">const</span> [count, setCount] = <span class="code-function">useState</span>(<span class="code-keyword">0</span>);<br>
                &nbsp;&nbsp;<span class="code-keyword">return</span> (<br>
                &nbsp;&nbsp;&nbsp;&nbsp;<span class="code-jsx">&lt;div&gt;</span><br>
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="code-jsx">&lt;p&gt;</span>You clicked {count} times<span class="code-jsx">&lt;/p&gt;</span><br>
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="code-jsx">&lt;button onClick=</span>{() => <span class="code-function">setCount</span>(count + <span class="code-keyword">1</span>)}<span class="code-jsx">&gt;</span><br>
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Click me<br>
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="code-jsx">&lt;/button&gt;</span><br>
                &nbsp;&nbsp;&nbsp;&nbsp;<span class="code-jsx">&lt;/div&gt;</span><br>
                &nbsp;&nbsp;);<br>
                }
            </div>
        </section>
        
        <section class="section">
            <h2 class="section-title">常用Hooks详解</h2>
            
            <div class="tabs">
                <div class="tab active" data-tab="useState">useState</div>
                <div class="tab" data-tab="useEffect">useEffect</div>
                <div class="tab" data-tab="useContext">useContext</div>
                <div class="tab" data-tab="useReducer">useReducer</div>
            </div>
            
            <div class="tab-content active" id="useState">
                <h3>useState - 状态管理</h3>
                <p>useState 是用于在函数组件中添加状态的最基本Hook。它返回一个状态值和一个更新该状态的函数。</p>
                
                <div class="code-block">
                    <span class="code-comment">// 基本用法</span><br>
                    <span class="code-keyword">import</span> React, { useState } <span class="code-keyword">from</span> <span class="code-string">'react'</span>;<br>
                    <br>
                    <span class="code-keyword">function</span> <span class="code-function">Counter</span>() {<br>
                    &nbsp;&nbsp;<span class="code-keyword">const</span> [count, setCount] = <span class="code-function">useState</span>(<span class="code-keyword">0</span>);<br>
                    &nbsp;&nbsp;<span class="code-keyword">return</span> (<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;<span class="code-jsx">&lt;div&gt;</span><br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="code-jsx">&lt;p&gt;</span>当前计数: {count}<span class="code-jsx">&lt;/p&gt;</span><br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="code-jsx">&lt;button onClick=</span>{() => <span class="code-function">setCount</span>(count + <span class="code-keyword">1</span>)}<span class="code-jsx">&gt;</span>+1<span class="code-jsx">&lt;/button&gt;</span><br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="code-jsx">&lt;button onClick=</span>{() => <span class="code-function">setCount</span>(count - <span class="code-keyword">1</span>)}<span class="code-jsx">&gt;</span>-1<span class="code-jsx">&lt;/button&gt;</span><br>
                    &nbsp;&nbsp;&nbsp;&nbsp;<span class="code-jsx">&lt;/div&gt;</span><br>
                    &nbsp;&nbsp;);<br>
                    }
                </div>
                
                <div class="demo-area">
                    <div class="demo-title"><i class="fas fa-play-circle"></i> useState 示例</div>
                    <div id="useStateDemo"></div>
                </div>
            </div>
            
            <div class="tab-content" id="useEffect">
                <h3>useEffect - 副作用处理</h3>
                <p>useEffect 用于在函数组件中执行副作用操作,如数据获取、订阅或手动修改DOM。</p>
                
                <div class="code-block">
                    <span class="code-comment">// 基本用法</span><br>
                    <span class="code-keyword">import</span> React, { useState, useEffect } <span class="code-keyword">from</span> <span class="code-string">'react'</span>;<br>
                    <br>
                    <span class="code-keyword">function</span> <span class="code-function">Example</span>() {<br>
                    &nbsp;&nbsp;<span class="code-keyword">const</span> [count, setCount] = <span class="code-function">useState</span>(<span class="code-keyword">0</span>);<br>
                    <br>
                    &nbsp;&nbsp;<span class="code-comment">// 类似于 componentDidMount 和 componentDidUpdate</span><br>
                    &nbsp;&nbsp;<span class="code-function">useEffect</span>(() => {<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;<span class="code-comment">// 更新文档标题</span><br>
                    &nbsp;&nbsp;&nbsp;&nbsp;document.title = <span class="code-string">`你点击了 ${count} 次`</span>;<br>
                    &nbsp;&nbsp;});<br>
                    <br>
                    &nbsp;&nbsp;<span class="code-keyword">return</span> (<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;<span class="code-jsx">&lt;div&gt;</span><br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="code-jsx">&lt;p&gt;</span>你点击了 {count} 次<span class="code-jsx">&lt;/p&gt;</span><br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="code-jsx">&lt;button onClick=</span>{() => <span class="code-function">setCount</span>(count + <span class="code-keyword">1</span>)}<span class="code-jsx">&gt;</span><br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;点击我<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="code-jsx">&lt;/button&gt;</span><br>
                    &nbsp;&nbsp;&nbsp;&nbsp;<span class="code-jsx">&lt;/div&gt;</span><br>
                    &nbsp;&nbsp;);<br>
                    }
                </div>
                
                <div class="demo-area">
                    <div class="demo-title"><i class="fas fa-play-circle"></i> useEffect 示例</div>
                    <div id="useEffectDemo"></div>
                </div>
            </div>
            
            <div class="tab-content" id="useContext">
                <h3>useContext - 上下文访问</h3>
                <p>useContext 用于在函数组件中访问React的Context,避免通过多级组件传递props。</p>
                
                <div class="code-block">
                    <span class="code-comment">// 基本用法</span><br>
                    <span class="code-keyword">import</span> React, { useContext } <span class="code-keyword">from</span> <span class="code-string">'react'</span>;<br>
                    <br>
                    <span class="code-comment">// 创建一个 Context</span><br>
                    <span class="code-keyword">const</span> ThemeContext = <span class="code-function">React.createContext</span>(<span class="code-string">'light'</span>);<br>
                    <br>
                    <span class="code-keyword">function</span> <span class="code-function">ThemedButton</span>() {<br>
                    &nbsp;&nbsp;<span class="code-comment">// 使用 useContext 获取当前主题</span><br>
                    &nbsp;&nbsp;<span class="code-keyword">const</span> theme = <span class="code-function">useContext</span>(ThemeContext);<br>
                    &nbsp;&nbsp;<span class="code-keyword">return</span> <span class="code-jsx">&lt;button className=</span>{theme}<span class="code-jsx">&gt;</span>当前主题: {theme}<span class="code-jsx">&lt;/button&gt;</span>;<br>
                    }<br>
                    <br>
                    <span class="code-keyword">function</span> <span class="code-function">App</span>() {<br>
                    &nbsp;&nbsp;<span class="code-keyword">return</span> (<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;<span class="code-jsx">&lt;ThemeContext.Provider value=</span><span class="code-string">"dark"</span><span class="code-jsx">&gt;</span><br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="code-jsx">&lt;ThemedButton /&gt;</span><br>
                    &nbsp;&nbsp;&nbsp;&nbsp;<span class="code-jsx">&lt;/ThemeContext.Provider&gt;</span><br>
                    &nbsp;&nbsp;);<br>
                    }
                </div>
                
                <div class="demo-area">
                    <div class="demo-title"><i class="fas fa-play-circle"></i> useContext 示例</div>
                    <div id="useContextDemo"></div>
                </div>
            </div>
            
            <div class="tab-content" id="useReducer">
                <h3>useReducer - 复杂状态管理</h3>
                <p>useReducer 是 useState 的替代方案,适用于状态逻辑较复杂或包含多个子值的场景。</p>
                
                <div class="code-block">
                    <span class="code-comment">// 基本用法</span><br>
                    <span class="code-keyword">import</span> React, { useReducer } <span class="code-keyword">from</span> <span class="code-string">'react'</span>;<br>
                    <br>
                    <span class="code-comment">// 定义reducer函数</span><br>
                    <span class="code-keyword">function</span> <span class="code-function">reducer</span>(state, action) {<br>
                    &nbsp;&nbsp;<span class="code-keyword">switch</span> (action.type) {<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;<span class="code-keyword">case</span> <span class="code-string">'increment'</span>:<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="code-keyword">return</span> { count: state.count + <span class="code-keyword">1</span> };<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;<span class="code-keyword">case</span> <span class="code-string">'decrement'</span>:<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="code-keyword">return</span> { count: state.count - <span class="code-keyword">1</span> };<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;<span class="code-keyword">default</span>:<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="code-keyword">throw</span> <span class="code-keyword">new</span> <span class="code-function">Error</span>();<br>
                    &nbsp;&nbsp;}<br>
                    }<br>
                    <br>
                    <span class="code-keyword">function</span> <span class="code-function">Counter</span>() {<br>
                    &nbsp;&nbsp;<span class="code-keyword">const</span> [state, dispatch] = <span class="code-function">useReducer</span>(reducer, { count: <span class="code-keyword">0</span> });<br>
                    &nbsp;&nbsp;<span class="code-keyword">return</span> (<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;<span class="code-jsx">&lt;&gt;</span><br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="code-jsx">&lt;p&gt;</span>计数: {state.count}<span class="code-jsx">&lt;/p&gt;</span><br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="code-jsx">&lt;button onClick=</span>{() => <span class="code-function">dispatch</span>({ type: <span class="code-string">'increment'</span> })}<span class="code-jsx">&gt;</span>+<span class="code-jsx">&lt;/button&gt;</span><br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="code-jsx">&lt;button onClick=</span>{() => <span class="code-function">dispatch</span>({ type: <span class="code-string">'decrement'</span> })}<span class="code-jsx">&gt;</span>-<span class="code-jsx">&lt;/button&gt;</span><br>
                    &nbsp;&nbsp;&nbsp;&nbsp;<span class="code-jsx">&lt;/&gt;</span><br>
                    &nbsp;&nbsp;);<br>
                    }
                </div>
                
                <div class="demo-area">
                    <div class="demo-title"><i class="fas fa-play-circle"></i> useReducer 示例</div>
                    <div id="useReducerDemo"></div>
                </div>
            </div>
        </section>
        
        <section class="section">
            <h2 class="section-title">自定义Hooks最佳实践</h2>
            <p>自定义Hooks是将组件逻辑提取到可重用函数的一种方式。以下是一些最佳实践:</p>
            
            <div class="best-practices">
                <div class="practice-item">
                    <i class="fas fa-check-circle practice-icon"></i>
                    <div>
                        <h3>命名约定</h3>
                        <p>自定义Hook的名称应该以"use"开头,这样React才能识别它并应用Hooks规则。</p>
                    </div>
                </div>
                
                <div class="practice-item">
                    <i class="fas fa-check-circle practice-icon"></i>
                    <div>
                        <h3>单一职责</h3>
                        <p>每个自定义Hook应该只负责一个特定的功能,保持简单和专注。</p>
                    </div>
                </div>
                
                <div class="practice-item">
                    <i class="fas fa-check-circle practice-icon"></i>
                    <div>
                        <h3>参数设计</h3>
                        <p>合理设计Hook的参数,使其既灵活又易于使用。考虑使用配置对象而不是多个参数。</p>
                    </div>
                </div>
                
                <div class="practice-item">
                    <i class="fas fa-check-circle practice-icon"></i>
                    <div>
                        <h3>返回值设计</h3>
                        <p>返回值的结构应该清晰且一致。考虑返回数组或对象,根据需要提供多个值。</p>
                    </div>
                </div>
            </div>
            
            <div class="code-block">
                <span class="code-comment">// 自定义Hook示例:useLocalStorage</span><br>
                <span class="code-keyword">import</span> { useState, useEffect } <span class="code-keyword">from</span> <span class="code-string">'react'</span>;<br>
                <br>
                <span class="code-keyword">function</span> <span class="code-function">useLocalStorage</span>(key, initialValue) {<br>
                &nbsp;&nbsp;<span class="code-comment">// 从localStorage获取初始值</span><br>
                &nbsp;&nbsp;<span class="code-keyword">const</span> [storedValue, setStoredValue] = <span class="code-function">useState</span>(() => {<br>
                &nbsp;&nbsp;&nbsp;&nbsp;<span class="code-keyword">try</span> {<br>
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="code-keyword">const</span> item = window.localStorage.<span class="code-function">getItem</span>(key);<br>
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="code-keyword">return</span> item ? <span class="code-function">JSON</span>.<span class="code-function">parse</span>(item) : initialValue;<br>
                &nbsp;&nbsp;&nbsp;&nbsp;} <span class="code-keyword">catch</span> (error) {<br>
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="code-keyword">return</span> initialValue;<br>
                &nbsp;&nbsp;&nbsp;&nbsp;}<br>
                &nbsp;&nbsp;});<br>
                <br>
                &nbsp;&nbsp;<span class="code-comment">// 返回包装后的setter函数,同时更新localStorage</span><br>
                &nbsp;&nbsp;<span class="code-keyword">const</span> setValue = (value) => {<br>
                &nbsp;&nbsp;&nbsp;&nbsp;<span class="code-keyword">try</span> {<br>
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="code-comment">// 允许值是一个函数,这样我们可以获得与useState相同的API</span><br>
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="code-keyword">const</span> valueToStore = value <span class="code-keyword">instanceof</span> Function ? <span class="code-function">value</span>(storedValue) : value;<br>
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="code-function">setStoredValue</span>(valueToStore);<br>
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;window.localStorage.<span class="code-function">setItem</span>(key, <span class="code-function">JSON</span>.<span class="code-function">stringify</span>(valueToStore));<br>
                &nbsp;&nbsp;&nbsp;&nbsp;} <span class="code-keyword">catch</span> (error) {<br>
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="code-function">console</span>.<span class="code-function">log</span>(error);<br>
                &nbsp;&nbsp;&nbsp;&nbsp;}<br>
                &nbsp;&nbsp;};<br>
                <br>
                &nbsp;&nbsp;<span class="code-keyword">return</span> [storedValue, setValue];<br>
                }<br>
                <br>
                <span class="code-comment">// 使用自定义Hook</span><br>
                <span class="code-keyword">function</span> <span class="code-function">MyComponent</span>() {<br>
                &nbsp;&nbsp;<span class="code-keyword">const</span> [name, setName] = <span class="code-function">useLocalStorage</span>(<span class="code-string">'name'</span>, <span class="code-string">'张三'</span>);<br>
                &nbsp;&nbsp;<span class="code-keyword">return</span> (<br>
                &nbsp;&nbsp;&nbsp;&nbsp;<span class="code-jsx">&lt;input value=</span>{name} onChange={e => <span class="code-function">setName</span>(e.target.value)} <span class="code-jsx">/&gt;</span><br>
                &nbsp;&nbsp;);<br>
                }
            </div>
            
            <div class="demo-area">
                <div class="demo-title"><i class="fas fa-play-circle"></i> 自定义Hook示例</div>
                <div id="customHookDemo"></div>
            </div>
        </section>
        
        <footer>
            <p>© 2023 React Hooks 设计哲学与最佳实践 | 探索React函数式组件的无限可能</p>
        </footer>
    </div>

    <script type="text/babel">
        // useState 示例组件
        function UseStateDemo() {
            const [count, setCount] = React.useState(0);
            
            return (
                <div className="hook-demo">
                    <div className="counter-display">计数: {count}</div>
                    <div className="demo-controls">
                        <button onClick={() => setCount(count + 1)}>增加</button>
                        <button onClick={() => setCount(count - 1)}>减少</button>
                        <button onClick={() => setCount(0)}>重置</button>
                    </div>
                </div>
            );
        }
        
        // useEffect 示例组件
        function UseEffectDemo() {
            const [count, setCount] = React.useState(0);
            const [time, setTime] = React.useState(new Date().toLocaleTimeString());
            
            React.useEffect(() => {
                // 更新文档标题
                document.title = `点击了 ${count} 次`;
            }, [count]);
            
            React.useEffect(() => {
                // 设置定时器
                const timer = setInterval(() => {
                    setTime(new Date().toLocaleTimeString());
                }, 1000);
                
                // 清理函数
                return () => clearInterval(timer);
            }, []);
            
            return (
                <div className="hook-demo">
                    <div className="counter-display">点击次数: {count}</div>
                    <div>当前时间: {time}</div>
                    <div className="demo-controls">
                        <button onClick={() => setCount(count + 1)}>点击我</button>
                    </div>
                </div>
            );
        }
        
        // useContext 示例组件
        const ThemeContext = React.createContext('light');
        
        function ThemedButton() {
            const theme = React.useContext(ThemeContext);
            return (
                <button style={{
                    padding: '10px 15px',
                    backgroundColor: theme === 'dark' ? '#333' : '#eee',
                    color: theme === 'dark' ? '#fff' : '#000',
                    border: 'none',
                    borderRadius: '4px'
                }}>
                    当前主题: {theme}
                </button>
            );
        }
        
        function UseContextDemo() {
            const [theme, setTheme] = React.useState('light');
            
            return (
                <div className="hook-demo">
                    <ThemeContext.Provider value={theme}>
                        <ThemedButton />
                    </ThemeContext.Provider>
                    <div className="demo-controls">
                        <button onClick={() => setTheme('light')}>浅色主题</button>
                        <button onClick={() => setTheme('dark')}>深色主题</button>
                    </div>
                </div>
            );
        }
        
        // useReducer 示例组件
        function reducer(state, action) {
            switch (action.type) {
                case 'increment':
                    return { count: state.count + 1 };
                case 'decrement':
                    return { count: state.count - 1 };
                case 'reset':
                    return { count: 0 };
                default:
                    throw new Error();
            }
        }
        
        function UseReducerDemo() {
            const [state, dispatch] = React.useReducer(reducer, { count: 0 });
            
            return (
                <div className="hook-demo">
                    <div className="counter-display">计数: {state.count}</div>
                    <div className="demo-controls">
                        <button onClick={() => dispatch({ type: 'increment' })}>增加</button>
                        <button onClick={() => dispatch({ type: 'decrement' })}>减少</button>
                        <button onClick={() => dispatch({ type: 'reset