全栈开发, 精选文章

nextjs 状态驱动的 UI

🔑 核心概念:状态驱动的 UI

1. UI 的显示/隐藏完全由状态决定

// 在 CategoryFormDialog 组件中
<Dialog open={categoryDialogOpen} onOpenChange={handleDialogOpenChange}>
  • categoryDialogOpentrue → 对话框显示
  • categoryDialogOpenfalse → 对话框隐藏
  • 没有手动控制,只有状态决定 UI

2. 状态是唯一的真相来源(Single Source of Truth)

// Zustand store 管理全局状态
const {
    selectedCategoryId,      // 当前选中的分类ID
    categoryDialogOpen       // 对话框是否打开
} = useCategoriesStore();

3. 用户交互 → 改变状态 → UI 自动更新

// 在其他组件中点击编辑按钮
<Button onClick={() => {
    updateSelectedCategoryId(item.id);    // 1. 改变状态:设置要编辑的ID
    updateCategoryDialogOpen(true);       // 2. 改变状态:打开对话框
}}>

// 结果:
// - selectedCategoryId 变为具体ID(编辑模式)
// - categoryDialogOpen 变为 true(对话框显示)
// - CategoryFormDialog 组件自动重新渲染,显示编辑界面

4. 数据流是单向的、可预测的

用户点击改变状态组件重新渲染UI 更新

5. 组件职责分离

  • CategoryFormDialog: 只负责"根据状态显示什么"
  • 其他组件: 只负责"什么时候改变状态"
  • Zustand store: 只负责"存储和管理状态"

6. 完整的工作流程

// 1. 用户点击编辑按钮(在其他组件中)
updateSelectedCategoryId("cat-123");
updateCategoryDialogOpen(true);

// 2. Zustand 状态更新
{
    selectedCategoryId: "cat-123",
    categoryDialogOpen: true
}

// 3. CategoryFormDialog 重新渲染
// - 检测到 categoryDialogOpen 为 true → 显示对话框
// - 检测到 selectedCategoryId 有值 → 进入编辑模式
// - useCategory() 根据 ID 获取数据 → useEffect 用数据填充表单

// 4. 用户提交后
handlerSuccess() → handleDialogOpenChange(false) → 
// 更新状态 categoryDialogOpen: false → 对话框自动关闭

7. 为什么这样设计?
可预测性: 任何时候 UI 都和状态保持一致
调试容易: 查看状态就知道 UI 应该是什么样子
测试友好: 改变状态就能测试 UI 变化
协作友好: 团队成员都能理解状态 → UI 的关系

🎯 一句话总结
你不是在"操作 UI",而是在"描述 UI 在某种状态下的样子"

这就是 React 声明式编程的核心:状态决定 UI,UI 反映状态。当你改变状态时,React 会自动计算出如何更新 UI,而不是你手动去操作 DOM。