文章
nextjs 状态驱动的 UI
🔑 核心概念:状态驱动的 UI
1. UI 的显示/隐藏完全由状态决定
// 在 CategoryFormDialog 组件中
<Dialog open={categoryDialogOpen} onOpenChange={handleDialogOpenChange}>categoryDialogOpen为true→ 对话框显示categoryDialogOpen为false→ 对话框隐藏- 没有手动控制,只有状态决定 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。