六十天前端强化训练之第十五天React组件基础案例:创建函数式组件展示用户信息(第15-21天:前端框架(React))

=====欢迎来到编程星辰海的博客讲解======

我们已经学了14天了,再坚持坚持,马上我们就可以变得更优秀了,加油,我相信大家,接下来的几天,我会给大家更新前端框架(React),看完可以给一个免费的三连吗,谢谢大佬!

代码都可以在godepen上运行的,大家可以复制代码试试

https://codepen.io/accounts/signup/user/free/year?ownerId=null&ownerType=null

目录

一、组件核心概念体系

[1.1 组件化开发哲学](#1.1 组件化开发哲学)

[1.2 虚拟DOM工作原理](#1.2 虚拟DOM工作原理)

二、函数式组件深度剖析

[2.1 基础结构](#2.1 基础结构)

[2.2 Hooks 生态系统](#2.2 Hooks 生态系统)

三、组件通信模式详解

[3.1 父→子通信(Props)](#3.1 父→子通信(Props))

[3.2 子→父通信(回调函数)](#3.2 子→父通信(回调函数))

[3.3 Context 跨层通信](#3.3 Context 跨层通信)

实战案例:带交互的用户信息管理

功能演示

关键知识点总结

状态管理策略

列表渲染最佳实践

表单处理模式

性能优化手段

扩展学习路径

官方文档精读

社区优质资源

推荐工具链

进阶挑战任务

一、为删除操作添加确认对话框

二、实现用户编辑功能

三、添加本地存储持久化

四、集成后端API接口

五、添加分页加载功能

六、实现角色权限控制

功能演示


一、组件核心概念体系

1.1 组件化开发哲学
  • 单一职责原则:每个组件应专注于单一功能
  • 封装性:内部实现细节对外隐藏,通过 Props 接口通信
  • 组合模式:通过组件嵌套形成树形结构
  • 可重用性:合理抽象提升组件复用率
1.2 虚拟DOM工作原理

JAVASCRIPT

复制代码
// 简化版虚拟DOM结构示例
const virtualNode = {
  type: 'div',
  props: {
    className: 'container',
    children: [
      { type: 'h1', props: { children: 'Hello World' } },
      { type: 'p', props: { children: 'React原理示例' } }
    ]
  }
};

Diff 算法通过以下策略优化更新:

  1. 同级比较策略
  2. Key 值优化列表比对
  3. 组件类型判断(相同类型复用实例)

二、函数式组件深度剖析

2.1 基础结构

JSX

复制代码
/**
 * 用户信息展示组件
 * @param {Object} props - 组件属性
 * @param {string} props.username - 用户名
 * @param {number} props.age - 用户年龄
 * @returns {JSX.Element} 用户信息卡片
 */
function UserInfo({ username, age }) {
  return (
    <div className="user-card">
      <h2>{username}</h2>
      <p>年龄: {age} 岁</p>
    </div>
  );
}
2.2 Hooks 生态系统

JSX

复制代码
import React, { useState, useEffect, useMemo } from 'react';

const UserDashboard = () => {
  // 状态管理:用户数据
  const [users, setUsers] = useState([]);
  
  // 状态管理:加载状态
  const [loading, setLoading] = useState(false);
  
  // 状态管理:错误信息
  const [error, setError] = useState(null);

  // 计算属性:用户总数
  const userCount = useMemo(
    () => users.filter(user => user.isActive).length,
    [users]
  );

  // 副作用:数据获取
  useEffect(() => {
    const fetchUsers = async () => {
      setLoading(true);
      try {
        const response = await fetch('/api/users');
        if (!response.ok) throw new Error('数据获取失败');
        const data = await response.json();
        setUsers(data);
      } catch (err) {
        setError(err.message);
      } finally {
        setLoading(false);
      }
    };

    fetchUsers();
  }, []); // 空依赖数组表示仅执行一次

  // 条件渲染处理
  if (loading) return <Spinner />;
  if (error) return <ErrorDisplay message={error} />;

  return (
    <div>
      <h3>总用户数: {userCount}</h3>
      <div className="user-list">
        {users.map(user => (
          <UserCard key={user.id} {...user} />
        ))}
      </div>
    </div>
  );
};

三、组件通信模式详解

3.1 父→子通信(Props)

JSX

复制代码
// 父组件
const UserManagement = () => {
  const [userList, setUserList] = useState(initialUsers);

  const handleUserUpdate = (updatedUser) => {
    setUserList(prev => 
      prev.map(user => 
        user.id === updatedUser.id ? updatedUser : user
      )
    );
  };

  return (
    <div>
      <UserTable 
        users={userList} 
        onEdit={handleUserUpdate}
      />
    </div>
  );
};

// 子组件
const UserTable = ({ users, onEdit }) => (
  <table>
    <thead>
      <tr>
        <th>姓名</th>
        <th>操作</th>
      </tr>
    </thead>
    <tbody>
      {users.map(user => (
        <tr key={user.id}>
          <td>{user.name}</td>
          <td>
            <button onClick={() => onEdit(user)}>
              编辑
            </button>
          </td>
        </tr>
      ))}
    </tbody>
  </table>
);
3.2 子→父通信(回调函数)

JSX

复制代码
const SearchBar = ({ onSearch }) => {
  const [query, setQuery] = useState('');

  const handleSubmit = (e) => {
    e.preventDefault();
    onSearch(query.trim());
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        value={query}
        onChange={(e) => setQuery(e.target.value)}
        placeholder="输入搜索关键词..."
      />
      <button type="submit">搜索</button>
    </form>
  );
};

// 父组件使用
<SearchBar onSearch={(keyword) => filterData(keyword)} />
3.3 Context 跨层通信

JSX

复制代码
// 创建 Context
const ThemeContext = React.createContext('light');

// 提供者组件
const App = () => {
  const [theme, setTheme] = useState('light');

  return (
    <ThemeContext.Provider value={{ theme, setTheme }}>
      <Toolbar />
    </ThemeContext.Provider>
  );
};

// 消费者组件
const ThemedButton = () => {
  const { theme, setTheme } = useContext(ThemeContext);

  return (
    <button 
      style={{ 
        background: theme === 'dark' ? '#333' : '#fff',
        color: theme === 'dark' ? '#fff' : '#333'
      }}
      onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}
    >
      切换主题
    </button>
  );
};

实战案例:带交互的用户信息管理

JSX

复制代码
import React, { useState, useEffect } from 'react';

/**
 * 用户信息管理系统
 * 功能:
 * 1. 展示用户列表
 * 2. 支持新增用户
 * 3. 支持删除用户
 * 4. 实时搜索过滤
 */
const UserManager = () => {
  // 主数据状态
  const [users, setUsers] = useState([]);
  
  // 搜索关键词状态
  const [searchTerm, setSearchTerm] = useState('');
  
  // 新用户表单状态
  const [newUser, setNewUser] = useState({
    name: '',
    email: '',
    role: 'user'
  });

  // 模拟初始化数据
  useEffect(() => {
    const initialUsers = [
      { id: 1, name: '张三', email: 'zhang@example.com', role: 'admin' },
      { id: 2, name: '李四', email: 'li@example.com', role: 'user' }
    ];
    setUsers(initialUsers);
  }, []);

  // 处理表单输入
  const handleInputChange = (e) => {
    const { name, value } = e.target;
    setNewUser(prev => ({
      ...prev,
      [name]: value
    }));
  };

  // 提交新用户
  const handleAddUser = (e) => {
    e.preventDefault();
    if (!newUser.name || !newUser.email) return;

    const userToAdd = {
      ...newUser,
      id: Date.now() // 临时ID生成方式
    };

    setUsers(prev => [...prev, userToAdd]);
    setNewUser({ name: '', email: '', role: 'user' });
  };

  // 删除用户
  const handleDelete = (userId) => {
    setUsers(prev => prev.filter(user => user.id !== userId));
  };

  // 过滤用户列表
  const filteredUsers = users.filter(user =>
    user.name.toLowerCase().includes(searchTerm.toLowerCase())
  );

  return (
    <div className="user-manager">
      {/* 搜索栏 */}
      <div className="search-section">
        <input
          type="text"
          placeholder="搜索用户..."
          value={searchTerm}
          onChange={(e) => setSearchTerm(e.target.value)}
        />
      </div>

      {/* 添加用户表单 */}
      <form onSubmit={handleAddUser} className="add-form">
        <input
          name="name"
          placeholder="姓名"
          value={newUser.name}
          onChange={handleInputChange}
          required
        />
        <input
          name="email"
          type="email"
          placeholder="邮箱"
          value={newUser.email}
          onChange={handleInputChange}
          required
        />
        <select
          name="role"
          value={newUser.role}
          onChange={handleInputChange}
        >
          <option value="user">普通用户</option>
          <option value="admin">管理员</option>
        </select>
        <button type="submit">添加用户</button>
      </form>

      {/* 用户列表 */}
      <div className="user-list">
        {filteredUsers.map(user => (
          <div key={user.id} className="user-card">
            <div className="user-info">
              <h3>{user.name}</h3>
              <p>{user.email}</p>
              <span className={`role-tag ${user.role}`}>
                {user.role === 'admin' ? '管理员' : '用户'}
              </span>
            </div>
            <button 
              className="delete-btn"
              onClick={() => handleDelete(user.id)}
            >
              删除
            </button>
          </div>
        ))}
      </div>
    </div>
  );
};

export default UserManager;

功能演示

  1. 实时搜索用户
  2. 添加新用户表单验证
  3. 用户角色标识
  4. 删除确认操作
  5. 响应式布局

关键知识点总结

状态管理策略
  • 使用 useState 管理组件内部状态
  • 状态提升:将共享状态移动到最近的共同祖先组件
  • 状态合并:使用扩展运算符保持状态不变性
列表渲染最佳实践
  • 始终提供稳定的 key 属性
  • 复杂列表使用虚拟滚动优化性能
  • 分离列表项为独立子组件
表单处理模式
  • 受控组件 vs 非受控组件
  • 表单验证实现方案
  • 使用 name 属性批量处理输入
性能优化手段
  • React.memo 记忆组件
  • useCallback 缓存函数引用
  • useMemo 避免重复计算
  • 按需加载组件 (React.lazy)
  1. 错误边界处理

    • 使用 try/catch 处理同步错误
    • 异步操作的错误处理
    • 全局错误边界组件

扩展学习路径

官方文档精读
社区优质资源
推荐工具链
  • 状态管理:Redux Toolkit / Recoil
  • 路由管理:React Router v6
  • 样式方案:Styled-components / CSS Modules
  • 测试框架:Jest + React Testing Library

进阶挑战任务

  1. 为删除操作添加确认对话框
  2. 实现用户编辑功能
  3. 添加本地存储持久化
  4. 集成后端 API 接口
  5. 添加分页加载功能
  6. 实现角色权限控制
一、为删除操作添加确认对话框

JSX

复制代码
const DeleteConfirmDialog = ({ onConfirm, onCancel }) => (
  <div className="confirm-dialog">
    <p>确定要删除该用户吗?</p>
    <div className="dialog-actions">
      <button onClick={onConfirm}>确认删除</button>
      <button onClick={onCancel}>取消</button>
    </div>
  </div>
);

// 使用示例
const handleDelete = (userId) => {
  const confirm = window.confirm('确定要删除该用户吗?');
  if (confirm) {
    setUsers(prev => prev.filter(user => user.id !== userId));
  }
};

二、实现用户编辑功能

JSX

复制代码
const UserEditor = ({ user, onSave, onCancel }) => {
  const [editData, setEditData] = useState(user);

  const handleSubmit = (e) => {
    e.preventDefault();
    onSave(editData);
  };

  return (
    <div className="edit-form">
      <form onSubmit={handleSubmit}>
        <input
          value={editData.name}
          onChange={(e) => setEditData({...editData, name: e.target.value})}
        />
        <input
          value={editData.email}
          onChange={(e) => setEditData({...editData, email: e.target.value})}
        />
        <div className="form-actions">
          <button type="submit">保存</button>
          <button type="button" onClick={onCancel}>取消</button>
        </div>
      </form>
    </div>
  );
};

// 在用户卡片中添加:
{isEditing ? (
  <UserEditor 
    user={user}
    onSave={(updated) => handleUpdateUser(updated)}
    onCancel={() => setEditingId(null)}
  />
) : (
  <button onClick={() => setEditingId(user.id)}>编辑</button>
)}

三、添加本地存储持久化

JSX

复制代码
// 自定义Hook
const useLocalStorage = (key, initialValue) => {
  const [value, setValue] = useState(() => {
    const stored = localStorage.getItem(key);
    return stored ? JSON.parse(stored) : initialValue;
  });

  useEffect(() => {
    localStorage.setItem(key, JSON.stringify(value));
  }, [key, value]);

  return [value, setValue];
};

// 使用示例
const [users, setUsers] = useLocalStorage('users', []);

四、集成后端API接口

JSX

复制代码
const api = {
  fetchUsers: async (page = 1) => {
    const response = await fetch(`/api/users?page=${page}`);
    return response.json();
  },
  
  createUser: async (user) => {
    const response = await fetch('/api/users', {
      method: 'POST',
      headers: {'Content-Type': 'application/json'},
      body: JSON.stringify(user)
    });
    return response.json();
  }
};

// 在组件中使用
useEffect(() => {
  const loadData = async () => {
    setLoading(true);
    try {
      const data = await api.fetchUsers();
      setUsers(data);
    } catch (err) {
      setError(err.message);
    } finally {
      setLoading(false);
    }
  };
  loadData();
}, []);

五、添加分页加载功能

JSX

复制代码
const Pagination = ({ current, total, onChange }) => (
  <div className="pagination">
    {Array.from({length: total}, (_, i) => (
      <button
        key={i+1}
        className={current === i+1 ? 'active' : ''}
        onClick={() => onChange(i+1)}
      >
        {i+1}
      </button>
    ))}
  </div>
);

// 使用示例
const [currentPage, setCurrentPage] = useState(1);
const [totalPages, setTotalPages] = useState(1);

useEffect(() => {
  const loadPage = async () => {
    const { data, total } = await api.fetchUsers(currentPage);
    setUsers(data);
    setTotalPages(total);
  };
  loadPage();
}, [currentPage]);

六、实现角色权限控制

JSX

复制代码
// 创建权限上下文
const AuthContext = React.createContext();

const AuthProvider = ({ children }) => {
  const [currentUser, setCurrentUser] = useState({
    role: 'admin' // 从登录获取实际值
  });

  const hasPermission = (requiredRole) => {
    return currentUser.role === requiredRole;
  };

  return (
    <AuthContext.Provider value={{ hasPermission }}>
      {children}
    </AuthContext.Provider>
  );
};

// 在组件中使用
const { hasPermission } = useContext(AuthContext);

{hasPermission('admin') && (
  <button onClick={handleEdit}>编辑</button>
)}

功能演示

每个功能模块都可以独立实现并逐步集成,建议按以下顺序进行开发:

  1. 添加本地存储持久化
  2. 实现API集成
  3. 添加分页功能
  4. 实现编辑功能
  5. 添加权限控制
  6. 最后实现确认对话框

通过本案例可以完整掌握 React 核心组件的开发流程,建议结合实际项目需求扩展功能模块。

相关推荐
崔庆才丨静觅7 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60618 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了8 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅8 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅9 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅9 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment9 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅9 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊9 小时前
jwt介绍
前端
爱敲代码的小鱼10 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax