← Frontend / 全栈实践

React项目实践

React 全栈项目前端的路由、状态、表单、测试与 Vue 版对照验收。

React 全栈项目实践

学习目标:使用 React 与 TypeScript 实现与 Vue 版等价的完整前端,并比较两种框架的设计取舍。

1. 先建立 React 模型

阅读 组件、Hooks 与状态、路由、数据与测试,再参考已有的 React 面试笔记。项目中使用函数组件和 Hooks,避免照搬 Vue 的响应式写法。

2. 模块结构

src/
  app/                 # 路由与全局提供者
  features/notes/api/  # API 客户端与响应解析
  features/notes/ui/   # 列表、表单、详情
  features/auth/       # 会话与路由保护
  shared/ui/           # 真正复用的组件

路由负责列表、详情、编辑和 404,筛选参数放 URL。组件的本地 UI 状态用 useState;服务端数据使用具备缓存和失效语义的数据获取层;useEffect 只处理外部同步,不把每个派生值都放进去。

3. 按里程碑实现

  1. 页面骨架:语义化 HTML、响应式布局、可见焦点和键盘操作。
  2. 读数据:封装请求,处理取消、加载、空结果、失败和重新获取。
  3. 写数据:表单校验、创建、编辑、删除与重复提交反馈。
  4. 会话与权限:区分未登录和无权访问;后端逐资源授权。
  5. 测试:React Testing Library 验证组件行为,Playwright 测试完整用户路径。
  6. 交付:类型检查、生产构建、环境配置、监控与回滚。

4. 与 Vue 版保持可比

同一验收标准:两版使用相同 API、示例数据、错误场景、可访问性要求和端到端测试意图。记录 Vue 的 computed/watch 与 React 的渲染派生/useEffect 在何处对应、何处不对应;不要机械翻译 API 名称。

5. 完成标准

  • 列表、搜索、CRUD、登录退出和无权限反馈与 Vue 版等价。
  • 旧请求和卸载后的异步回调不会覆盖当前页面状态。
  • 窄屏、键盘与辅助技术路径可用。
  • 测试和构建由 CI 从干净环境复现。
易错点:不要把后端返回的 JSON 用类型断言直接当作可信数据;先在 API 边界验证。

6. 一条 React 纵向链路

先完成“打开列表—创建笔记—返回列表”。路由负责 /notes 和 /notes/new;API 函数负责请求、状态码映射与 JSON 校验;数据获取层管理列表缓存及创建后的失效;组件只处理表单输入、用户反馈和导航。不要在渲染过程中发请求,提交放在事件处理函数中。

import { useState, type FormEvent } from 'react';

function NoteTitleForm({ onSave }: { onSave: (title: string) => Promise<void> }) {
  const [title, setTitle] = useState('');
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState('');

  async function submit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    if (!title.trim() || saving) return;
    setSaving(true);
    setError('');
    try { await onSave(title.trim()); }
    catch { setError('保存失败,请重试'); }
    finally { setSaving(false); }
  }

  return <form onSubmit={submit}>
    <label htmlFor="title">标题</label>
    <input id="title" value={title} onChange={e => setTitle(e.target.value)} />
    <button type="submit" disabled={!title.trim() || saving}>保存</button>
    {error && <p role="alert">{error}</p>}
  </form>;
}

真实页面还需字段级错误、409 冲突与 401/403 的区别。saving 防止普通重复点击,但服务端仍需负责幂等。保存成功后的导航与缓存失效由调用方处理,使表单可独立测试。

7. 对照 Vue 的验收

两版共享 API 契约、测试数据和用户路径。比较 useState 与 Vue ref、渲染时派生值与 computed、Effect 与 watch 的适用场景;不要用一个框架的写法机械模拟另一个。分别验证列表空状态、旧请求取消、创建失败保留输入、键盘流程和越权拒绝。