React 组件复用与高级技术详解

✅ 适用于 React 18+(含 Hooks、函数组件主流写法)
⚠️ 注意:mixins 已废弃,不推荐在新项目中使用


一、组件分离(Component Separation)

概念:将 UI 或逻辑拆分成独立、可复用的小型组件,提高可维护性和复用性。

✅ 语法与使用:

// Button.jsx —— 基础按钮组件
import React from 'react';
import './Button.css'; // 可选样式文件

const Button = ({ onClick, children, variant = 'primary', disabled = false }) => {
  return (
    <button
      className={`btn btn-${variant}`}
      onClick={onClick}
      disabled={disabled}
    >
      {children}
    </button>
  );
};

export default Button;
// App.jsx —— 使用分离组件
import React from 'react';
import Button from './components/Button';

const App = () => {
  const handleClick = () => {
    alert('按钮被点击!');
  };

  return (
    <div>
      <h1>组件分离示例</h1>
      <Button onClick={handleClick}>普通按钮</Button>
      <Button variant="danger" disabled>禁用按钮</Button>
    </div>
  );
};

export default App;

二、组件嵌套(Component Nesting)

概念:父组件中包含子组件,形成树状结构。可通过 children 属性传递内容。

✅ 语法与使用:

// Card.jsx —— 卡片容器组件
import React from 'react';

const Card = ({ title, children, className = '' }) => {
  return (
    <div className={`card ${className}`}>
      <div className="card-header">
        <h3>{title}</h3>
      </div>
      <div className="card-body">
        {children} {/* 嵌套内容 */}
      </div>
    </div>
  );
};

export default Card;
// App.jsx —— 使用嵌套组件
import React from 'react';
import Card from './components/Card';
import Button from './components/Button';

const App = () => {
  return (
    <div>
      <Card title="用户信息">
        <p>姓名:张三</p>
        <p>年龄:25</p>
        <Button>编辑</Button>
      </Card>

      <Card title="操作区" className="mt-4">
        <Button variant="success">保存</Button>
        <Button variant="danger">删除</Button>
      </Card>
    </div>
  );
};

export default App;

三、动态组件(Dynamic Components)

概念:根据条件或状态动态渲染不同的组件。

✅ 语法与使用:

// components/index.js —— 组件映射表
import Home from './Home';
import About from './About';
import Contact from './Contact';

export const componentMap = {
  home: Home,
  about: About,
  contact: Contact,
};
// DynamicComponent.jsx
import React from 'react';
import { componentMap } from './components';

const DynamicComponent = ({ componentName, ...props }) => {
  const Component = componentMap[componentName];

  if (!Component) {
    return <div>组件未找到: {componentName}</div>;
  }

  return <Component {...props} />;
};

export default DynamicComponent;
// App.jsx —— 使用动态组件
import React, { useState } from 'react';
import DynamicComponent from './DynamicComponent';

const App = () => {
  const [currentTab, setCurrentTab] = useState('home');

  return (
    <div>
      <nav>
        <button onClick={() => setCurrentTab('home')}>首页</button>
        <button onClick={() => setCurrentTab('about')}>关于</button>
        <button onClick={() => setCurrentTab('contact')}>联系</button>
      </nav>

      <main>
        <DynamicComponent componentName={currentTab} />
      </main>
    </div>
  );
};

export default App;

四、组件间通信(Component Communication)

1. 父 → 子:通过 props 传递

// Child.jsx
const Child = ({ message, onUpdate }) => {
  return (
    <div>
      <p>来自父组件: {message}</p>
      <button onClick={() => onUpdate('子组件更新了数据!')}>
        通知父组件
      </button>
    </div>
  );
};
// Parent.jsx
import React, { useState } from 'react';
import Child from './Child';

const Parent = () => {
  const [data, setData] = useState('初始数据');

  const handleUpdate = (newData) => {
    setData(newData);
  };

  return (
    <div>
      <h2>父组件数据: {data}</h2>
      <Child message={data} onUpdate={handleUpdate} />
    </div>
  );
};

2. 子 → 父:通过回调函数

(见上例)

3. 兄弟组件通信:通过共同父组件状态提升

// SiblingA.jsx
const SiblingA = ({ onSendData }) => {
  return (
    <div>
      <input
        type="text"
        onChange={(e) => onSendData(e.target.value)}
        placeholder="输入内容给兄弟组件"
      />
    </div>
  );
};
// SiblingB.jsx
const SiblingB = ({ receivedData }) => {
  return <div>兄弟组件收到: {receivedData || '无数据'}</div>;
};
// Parent.jsx
import React, { useState } from 'react';
import SiblingA from './SiblingA';
import SiblingB from './SiblingB';

const Parent = () => {
  const [sharedData, setSharedData] = useState('');

  return (
    <div>
      <SiblingA onSendData={setSharedData} />
      <SiblingB receivedData={sharedData} />
    </div>
  );
};

五、事件回调机制(Event Callback)

概念:子组件通过 props 接收父组件传递的函数,在事件触发时调用。

// InputField.jsx
const InputField = ({ label, value, onChange, placeholder }) => {
  return (
    <div>
      <label>{label}</label>
      <input
        type="text"
        value={value}
        onChange={(e) => onChange(e.target.value)} // 触发回调
        placeholder={placeholder}
      />
    </div>
  );
};
// Form.jsx
import React, { useState } from 'react';
import InputField from './InputField';

const Form = () => {
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');

  const handleSubmit = () => {
    alert(`提交数据: ${name}, ${email}`);
  };

  return (
    <form>
      <InputField
        label="姓名"
        value={name}
        onChange={setName}
        placeholder="请输入姓名"
      />
      <InputField
        label="邮箱"
        value={email}
        onChange={setEmail}
        placeholder="请输入邮箱"
      />
      <button type="button" onClick={handleSubmit}>
        提交
      </button>
    </form>
  );
};

六、公开组件功能(Expose Component Methods)

概念:通过 useImperativeHandle + forwardRef 暴露组件内部方法给父组件调用。

// Modal.jsx
import React, { useImperativeHandle, useRef, useState } from 'react';

const Modal = React.forwardRef((props, ref) => {
  const [visible, setVisible] = useState(false);

  // 暴露方法给父组件
  useImperativeHandle(ref, () => ({
    show: () => setVisible(true),
    hide: () => setVisible(false),
    toggle: () => setVisible(!visible),
  }));

  if (!visible) return null;

  return (
    <div className="modal-overlay">
      <div className="modal">
        <h3>模态框</h3>
        <p>{props.children}</p>
        <button onClick={() => setVisible(false)}>关闭</button>
      </div>
    </div>
  );
});

export default Modal;
// App.jsx
import React, { useRef } from 'react';
import Modal from './Modal';

const App = () => {
  const modalRef = useRef();

  return (
    <div>
      <button onClick={() => modalRef.current?.show()}>打开模态框</button>
      <button onClick={() => modalRef.current?.hide()}>关闭模态框</button>
      <button onClick={() => modalRef.current?.toggle()}>切换显示</button>

      <Modal ref={modalRef}>
        <p>这是模态框内容</p>
      </Modal>
    </div>
  );
};

七、动态参数传递(Dynamic Props Passing)

概念:使用扩展运算符 ... 动态传递 props。

// DynamicPropsComponent.jsx
const DynamicPropsComponent = (props) => {
  return (
    <div {...props} style={{ padding: '10px', border: '1px solid #ccc' }}>
      <h4>动态属性组件</h4>
      <p>所有传入属性: {JSON.stringify(props)}</p>
    </div>
  );
};
// App.jsx
import React from 'react';
import DynamicPropsComponent from './DynamicPropsComponent';

const App = () => {
  const baseProps = {
    id: 'my-component',
    className: 'custom-class',
    'data-test': 'dynamic-component',
  };

  const extraProps = {
    onClick: () => alert('被点击了!'),
    tabIndex: 0,
  };

  return (
    <div>
      <DynamicPropsComponent {...baseProps} {...extraProps}>
        内容区域
      </DynamicPropsComponent>
    </div>
  );
};

八、组件逻辑复用(Logic Reuse)

方式1:自定义 Hook(推荐)

// hooks/useCounter.js
import { useState, useCallback } from 'react';

export const useCounter = (initialValue = 0) => {
  const [count, setCount] = useState(initialValue);

  const increment = useCallback(() => setCount(c => c + 1), []);
  const decrement = useCallback(() => setCount(c => c - 1), []);
  const reset = useCallback(() => setCount(initialValue), [initialValue]);

  return {
    count,
    increment,
    decrement,
    reset,
  };
};
// CounterA.jsx
import React from 'react';
import { useCounter } from '../hooks/useCounter';

const CounterA = () => {
  const { count, increment, decrement, reset } = useCounter(10);

  return (
    <div>
      <h4>计数器 A</h4>
      <p>值: {count}</p>
      <button onClick={increment}>+</button>
      <button onClick={decrement}>-</button>
      <button onClick={reset}>重置</button>
    </div>
  );
};

export default CounterA;
// CounterB.jsx —— 复用相同逻辑
import React from 'react';
import { useCounter } from '../hooks/useCounter';

const CounterB = () => {
  const { count, increment } = useCounter(0);

  return (
    <div>
      <h4>计数器 B(只增)</h4>
      <p>值: {count}</p>
      <button onClick={increment}>点我加一</button>
    </div>
  );
};

export default CounterB;

九、mixins机制(已废弃,仅作了解)

⚠️ React 官方已废弃 mixins,推荐使用 自定义 Hook高阶组件 替代。

// ❌ 不推荐写法(仅历史参考)
var SetIntervalMixin = {
  componentWillMount: function() {
    this.intervals = [];
  },
  setInterval: function() {
    this.intervals.push(setInterval.apply(null, arguments));
  },
  componentWillUnmount: function() {
    this.intervals.forEach(clearInterval);
  }
};

var TickTock = React.createClass({
  mixins: [SetIntervalMixin], // 已废弃
  // ...
});

十、渲染属性(Render Props)

概念:组件接收一个函数作为 prop,该函数返回 React 元素,实现逻辑复用。

// MouseTracker.jsx
import React, { useState, useEffect } from 'react';

const MouseTracker = ({ render }) => {
  const [position, setPosition] = useState({ x: 0, y: 0 });

  useEffect(() => {
    const handleMouseMove = (e) => {
      setPosition({ x: e.clientX, y: e.clientY });
    };

    window.addEventListener('mousemove', handleMouseMove);
    return () => window.removeEventListener('mousemove', handleMouseMove);
  }, []);

  return render(position); // 调用 render prop
};
// App.jsx
import React from 'react';
import MouseTracker from './MouseTracker';

const App = () => {
  return (
    <div>
      <h2>鼠标位置追踪(Render Props)</h2>
      <MouseTracker
        render={(mouse) => (
          <p>
            鼠标位置: X: {mouse.x}, Y: {mouse.y}
          </p>
        )}
      />

      <MouseTracker
        render={(mouse) => (
          <div
            style={{
              position: 'absolute',
              left: mouse.x,
              top: mouse.y,
              transform: 'translate(-50%, -50%)',
              width: '20px',
              height: '20px',
              background: 'red',
              borderRadius: '50%',
            }}
          />
        )}
      />
    </div>
  );
};

十一、高阶组件(Higher-Order Component, HOC)

1. 高阶组件概念

定义:接收一个组件,返回一个新组件的函数。

2. 高阶组件与属性代理(Props Proxy)

// withLogger.js
import React from 'react';

// 高阶组件:添加日志功能
const withLogger = (WrappedComponent) => {
  const WithLogger = (props) => {
    console.log('组件渲染,props:', props);

    return <WrappedComponent {...props} />;
  };

  WithLogger.displayName = `WithLogger(${WrappedComponent.displayName || WrappedComponent.name})`;

  return WithLogger;
};

export default withLogger;
// UserProfile.jsx
import React from 'react';
import withLogger from './withLogger';

const UserProfile = ({ name, email }) => {
  return (
    <div>
      <h3>用户资料</h3>
      <p>姓名: {name}</p>
      <p>邮箱: {email}</p>
    </div>
  );
};

// 使用 HOC 增强
export default withLogger(UserProfile);

3. 高阶组件与异步数据请求

// withData.js
import React, { useState, useEffect } from 'react';

// 通用数据获取 HOC
const withData = (url, propName = 'data') => (WrappedComponent) => {
  return (props) => {
    const [data, setData] = useState(null);
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState(null);

    useEffect(() => {
      const fetchData = async () => {
        try {
          const response = await fetch(url);
          if (!response.ok) throw new Error('请求失败');
          const result = await response.json();
          setData(result);
        } catch (err) {
          setError(err.message);
        } finally {
          setLoading(false);
        }
      };

      fetchData();
    }, [url]);

    if (loading) return <div>加载中...</div>;
    if (error) return <div>错误: {error}</div>;

    return <WrappedComponent {...props} {...{ [propName]: data }} />;
  };
};

export default withData;
// UserList.jsx
import React from 'react';
import withData from './withData';

const UserList = ({ users }) => {
  return (
    <div>
      <h3>用户列表</h3>
      <ul>
        {users.map((user) => (
          <li key={user.id}>{user.name}</li>
        ))}
      </ul>
    </div>
  );
};

// 增强:自动获取用户数据
export default withData('https://jsonplaceholder.typicode.com/users', 'users')(UserList);

十二、Context 机制(跨层级组件通信)

✅ 创建与使用 Context

// ThemeContext.js
import React, { createContext, useContext, useState } from 'react';

// 创建 Context
const ThemeContext = createContext();

// 自定义 Hook 方便使用
export const useTheme = () => {
  const context = useContext(ThemeContext);
  if (!context) {
    throw new Error('useTheme 必须在 ThemeProvider 内使用');
  }
  return context;
};

// Provider 组件
export const ThemeProvider = ({ children }) => {
  const [theme, setTheme] = useState('light');

  const toggleTheme = () => {
    setTheme((prev) => (prev === 'light' ? 'dark' : 'light'));
  };

  return (
    <ThemeContext.Provider value={{ theme, toggleTheme }}>
      {children}
    </ThemeContext.Provider>
  );
};
// ThemedButton.jsx
import React from 'react';
import { useTheme } from './ThemeContext';

const ThemedButton = () => {
  const { theme, toggleTheme } = useTheme();

  return (
    <button
      onClick={toggleTheme}
      style={{
        background: theme === 'dark' ? '#333' : '#eee',
        color: theme === 'dark' ? '#fff' : '#000',
        padding: '10px 20px',
        border: 'none',
        cursor: 'pointer',
      }}
    >
      当前主题: {theme} | 点击切换
    </button>
  );
};

export default ThemedButton;
// App.jsx
import React from 'react';
import { ThemeProvider } from './ThemeContext';
import ThemedButton from './ThemedButton';

const App = () => {
  return (
    <ThemeProvider>
      <div>
        <h1>Context 主题切换示例</h1>
        <ThemedButton />
        <ThemedButton /> {/* 多个组件共享状态 */}
      </div>
    </ThemeProvider>
  );
};

export default App;

十三、React Hook 技术(核心复用逻辑方式)

常用 Hooks:

  • useState – 状态管理
  • useEffect – 副作用
  • useContext – 使用 Context
  • useReducer – 复杂状态逻辑
  • useCallback / useMemo – 性能优化
  • useRef – 引用 DOM 或保存可变值
  • useImperativeHandle – 暴露命令式方法
  • useLayoutEffect – 同步副作用

✅ 自定义 Hook 示例:表单处理

// hooks/useForm.js
import { useState, useCallback } from 'react';

export const useForm = (initialValues = {}) => {
  const [values, setValues] = useState(initialValues);
  const [errors, setErrors] = useState({});

  const handleChange = useCallback((e) => {
    const { name, value } = e.target;
    setValues((prev) => ({ ...prev, [name]: value }));
    // 清除对应错误
    if (errors[name]) {
      setErrors((prev) => ({ ...prev, [name]: undefined }));
    }
  }, [errors]);

  const setFieldError = useCallback((fieldName, errorMsg) => {
    setErrors((prev) => ({ ...prev, [fieldName]: errorMsg }));
  }, []);

  const validate = useCallback((validators) => {
    const newErrors = {};
    for (const field in validators) {
      const error = validators[field](values[field]);
      if (error) newErrors[field] = error;
    }
    setErrors(newErrors);
    return Object.keys(newErrors).length === 0;
  }, [values]);

  const reset = useCallback(() => {
    setValues(initialValues);
    setErrors({});
  }, [initialValues]);

  return {
    values,
    errors,
    handleChange,
    setFieldError,
    validate,
    reset,
  };
};
// LoginForm.jsx
import React from 'react';
import { useForm } from '../hooks/useForm';

const LoginForm = () => {
  const { values, errors, handleChange, validate } = useForm({
    username: '',
    password: '',
  });

  const handleSubmit = (e) => {
    e.preventDefault();

    const isValid = validate({
      username: (val) => (!val ? '用户名不能为空' : ''),
      password: (val) => (!val ? '密码不能为空' : val.length < 6 ? '密码至少6位' : ''),
    });

    if (isValid) {
      alert('登录成功!');
      console.log('提交数据:', values);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label>用户名:</label>
        <input
          name="username"
          value={values.username}
          onChange={handleChange}
        />
        {errors.username && <span style={{ color: 'red' }}>{errors.username}</span>}
      </div>

      <div>
        <label>密码:</label>
        <input
          name="password"
          type="password"
          value={values.password}
          onChange={handleChange}
        />
        {errors.password && <span style={{ color: 'red' }}>{errors.password}</span>}
      </div>

      <button type="submit">登录</button>
    </form>
  );
};

export default LoginForm;

十四、Store 机制(状态管理)

通常指 Redux、Zustand、Jotai、Recoil 等全局状态管理库。这里以 Zustand(轻量推荐) 为例:

安装:

npm install zustand

✅ 使用示例:

// store/userStore.js
import { create } from 'zustand';

const useUserStore = create((set) => ({
  user: null,
  token: null,

  login: (userData, token) => set({ user: userData, token }),
  logout: () => set({ user: null, token: null }),

  updateUser: (updates) =>
    set((state) => ({
      user: { ...state.user, ...updates },
    })),
}));
// UserProfile.jsx
import React from 'react';
import { useUserStore } from '../store/userStore';

const UserProfile = () => {
  const { user, logout } = useUserStore();

  if (!user) return <div>请先登录</div>;

  return (
    <div>
      <h3>欢迎, {user.name}!</h3>
      <p>邮箱: {user.email}</p>
      <button onClick={logout}>退出登录</button>
    </div>
  );
};

export default UserProfile;
// LoginButton.jsx
import React from 'react';
import { useUserStore } from '../store/userStore';

const LoginButton = () => {
  const { user, login } = useUserStore();

  const handleLogin = () => {
    login(
      { id: 1, name: '张三', email: 'zhang@example.com' },
      'fake-jwt-token-123'
    );
  };

  if (user) return null;

  return <button onClick={handleLogin}>模拟登录</button>;
};

export default LoginButton;
// App.jsx
import React from 'react';
import LoginButton from './LoginButton';
import UserProfile from './UserProfile';

const App = () => {
  return (
    <div>
      <h1>Store 状态管理示例</h1>
      <LoginButton />
      <UserProfile />
    </div>
  );
};

export default App;

十五、本章小结

技术 适用场景 推荐度
组件分离/嵌套 基础 UI 拆分 ⭐⭐⭐⭐⭐
动态组件 路由/Tab 切换 ⭐⭐⭐⭐
Props 通信 父子组件 ⭐⭐⭐⭐⭐
Context 跨层级状态共享(主题、语言等) ⭐⭐⭐⭐
自定义 Hook 逻辑复用(表单、请求、计时器等) ⭐⭐⭐⭐⭐
高阶组件 (HOC) 包装增强组件(日志、权限、数据) ⭐⭐⭐
Render Props 逻辑复用(较灵活但 JSX 嵌套深) ⭐⭐
Store (Zustand/Redux) 全局复杂状态管理 ⭐⭐⭐⭐
Ref + ImperativeHandle 暴露命令式方法(如表单校验) ⭐⭐⭐

📌 现代 React 开发推荐组合

  • UI 拆分 → 组件分离 + 嵌套
  • 状态管理 → useState + useContext(中小型) / Zustand(中大型)
  • 逻辑复用 → 自定义 Hook
  • 跨组件通信 → Context + Zustand
  • 命令式控制 → useImperativeHandle + forwardRef

🔥 综合案例:Todo 应用(涵盖多种技术)

// hooks/useTodos.js
import { useState, useCallback } from 'react';

export const useTodos = () => {
  const [todos, setTodos] = useState([
    { id: 1, text: '学习 React', completed: false },
    { id: 2, text: '写代码', completed: true },
  ]);

  const addTodo = useCallback((text) => {
    if (!text.trim()) return;
    setTodos((prev) => [
      ...prev,
      { id: Date.now(), text, completed: false },
    ]);
  }, []);

  const toggleTodo = useCallback((id) => {
    setTodos((prev) =>
      prev.map((todo) =>
        todo.id === id ? { ...todo, completed: !todo.completed } : todo
      )
    );
  }, []);

  const deleteTodo = useCallback((id) => {
    setTodos((prev) => prev.filter((todo) => todo.id !== id));
  }, []);

  const editTodo = useCallback((id, newText) => {
    setTodos((prev) =>
      prev.map((todo) =>
        todo.id === id ? { ...todo, text: newText } : todo
      )
    );
  }, []);

  return {
    todos,
    addTodo,
    toggleTodo,
    deleteTodo,
    editTodo,
  };
};
// components/TodoItem.jsx
import React, { useState } from 'react';

const TodoItem = ({ todo, onToggle, onDelete, onEdit }) => {
  const [isEditing, setIsEditing] = useState(false);
  const [editText, setEditText] = useState(todo.text);

  const handleSave = () => {
    if (editText.trim()) {
      onEdit(todo.id, editText);
    }
    setIsEditing(false);
  };

  if (isEditing) {
    return (
      <div>
        <input
          value={editText}
          onChange={(e) => setEditText(e.target.value)}
          onBlur={handleSave}
          onKeyPress={(e) => e.key === 'Enter' && handleSave()}
          autoFocus
        />
        <button onClick={handleSave}>保存</button>
      </div>
    );
  }

  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>
      <input
        type="checkbox"
        checked={todo.completed}
        onChange={() => onToggle(todo.id)}
      />
      <span
        style={{
          textDecoration: todo.completed ? 'line-through' : 'none',
          cursor: 'pointer',
        }}
        onDoubleClick={() => setIsEditing(true)}
      >
        {todo.text}
      </span>
      <button onClick={() => setIsEditing(true)}>编辑</button>
      <button onClick={() => onDelete(todo.id)}>删除</button>
    </div>
  );
};

export default TodoItem;
// components/TodoInput.jsx
import React, { useState } from 'react';

const TodoInput = ({ onAdd }) => {
  const [text, setText] = useState('');

  const handleSubmit = (e) => {
    e.preventDefault();
    if (text.trim()) {
      onAdd(text);
      setText('');
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        value={text}
        onChange={(e) => setText(e.target.value)}
        placeholder="添加新任务..."
        style={{ padding: '8px', marginRight: '8px' }}
      />
      <button type="submit">添加</button>
    </form>
  );
};

export default TodoInput;
// App.jsx —— 综合使用
import React from 'react';
import { useTodos } from './hooks/useTodos';
import TodoInput from './components/TodoInput';
import TodoItem from './components/TodoItem';

const App = () => {
  const { todos, addTodo, toggleTodo, deleteTodo, editTodo } = useTodos();

  const activeCount = todos.filter((t) => !t.completed).length;
  const completedCount = todos.length - activeCount;

  return (
    <div style={{ maxWidth: '500px', margin: '50px auto', padding: '20px' }}>
      <h1>Todo 应用(综合案例)</h1>
      <TodoInput onAdd={addTodo} />

      <div style={{ marginTop: '20px' }}>
        <h3>任务列表 ({activeCount} 未完成, {completedCount} 已完成)</h3>
        {todos.length === 0 ? (
          <p>暂无任务</p>
        ) : (
          <div>
            {todos.map((todo) => (
              <TodoItem
                key={todo.id}
                todo={todo}
                onToggle={toggleTodo}
                onDelete={deleteTodo}
                onEdit={editTodo}
              />
            ))}
          </div>
        )}
      </div>
    </div>
  );
};

export default App;

本综合案例涵盖技术点

  • 组件分离(TodoItem, TodoInput)
  • 自定义 Hook(useTodos)
  • 事件回调(onAdd, onToggle…)
  • 动态渲染(列表映射)
  • 状态管理(useState + useCallback)
  • 条件渲染(编辑模式切换)
  • Props 传递与解构

📚 学习建议

  1. 从组件分离和 Props 通信开始打基础
  2. 掌握自定义 Hook 实现逻辑复用
  3. Context 用于主题、语言、用户等全局状态
  4. 复杂项目引入 Zustand/Redux 管理 Store
  5. HOC 和 Render Props 了解即可,优先使用 Hook

🎯 至此,你已掌握 React 组件复用与高级技术的核心内容!可应对绝大多数实际项目需求。

更多推荐