首页
/ UI2项目实战:如何为React应用添加意图(Intents)

UI2项目实战:如何为React应用添加意图(Intents)

2025-06-06 19:10:56作者:滑思眉Philip

前言

在现代前端开发中,构建交互式应用需要处理复杂的用户意图和状态管理。UI2项目提供了一种声明式的方式来处理这些交互,本文将深入探讨如何在React应用中添加和管理意图(Intents)。

什么是UI2意图?

UI2意图是一种高级抽象,它封装了用户操作的完整生命周期。每个意图包含三个关键阶段:

  1. onIntent - 当用户表达意图时触发,通常用于显示操作预览
  2. onCleanup - 当用户取消或意图未完成时触发,用于清理状态
  3. onSubmit - 当用户确认意图时触发,执行最终操作

这种模式特别适合需要预览-确认流程的交互场景。

添加待办事项(addTodo)意图

1. 基本设置

首先,我们需要在useUI2钩子上调用.addIntent()方法:

let { inputValue, handleInputChange, handleSubmit } = useUI2({
  model: cerebras("llama-3.3-70b"),
  systemPrompt: "This is a todo app.",
  context: todos.filter((x) => !x.preview),
}).addIntent("addTodo", {
  description: "Add a todo",
  parameters: z.object({
    name: z.string(),
  }),
});

这里使用了Zod库来定义参数类型,确保AI输出的结构化数据符合预期。

2. 实现onIntent回调

onIntent阶段应该显示操作预览:

onIntent: ({ parameters, id }) => {
  setTodos((prev) => [
    ...prev,
    {
      id,
      name: parameters.name,
      completed: false,
      preview: true,
    },
  ]);
},

关键点:

  • 使用preview标记区分预览状态
  • 利用意图ID跟踪特定操作
  • 保持状态不可变更新

3. 实现onCleanup回调

当意图取消时,需要清理预览状态:

onCleanup: ({ id }) => {
  setTodos((prev) => prev.filter((x) => x.id !== id));
},

注意我们使用意图ID而非名称来识别待办事项,这更可靠。

4. 实现onSubmit回调

用户确认后,将预览转为正式项:

onSubmit: ({ id }) =>
  setTodos((prev) =>
    prev.map((x) => (x.id === id ? { ...x, preview: false } : x))
  ),

完成待办事项(completeTodo)意图

这个意图展示了如何操作现有项:

.addIntent("completeTodo", {
  description: "complete a todo",
  parameters: z.object({
    id: z.string(),
  }),
  onIntent: ({ parameters }) => {
    setTodos((prev) =>
      prev.map((x) =>
        x.id === parameters.id
          ? { ...x, preview: true, completed: true }
          : x
      )
    );
  },
  onCleanup: ({ parameters }) => {
    setTodos((prev) =>
      prev.map((x) =>
        x.id === parameters.id
          ? { ...x, preview: false, completed: false }
          : x
      )
    );
  },
  onSubmit: ({ parameters }) =>
    setTodos((prev) =>
      prev.map((x) =>
        x.id === parameters.id
          ? { ...x, preview: false, completed: true }
          : x
      )
    ),
});

关键区别:

  • 操作现有项而非新增
  • 参数ID引用待办事项ID
  • 状态转换更复杂

最佳实践

  1. 保持参数简单:虽然Zod支持复杂模式,但简单结构更可靠
  2. 充分利用意图ID:这是跟踪操作生命周期的可靠标识
  3. 预览模式一致性:所有意图都应遵循预览-确认模式
  4. 状态管理清晰:确保onIntent、onCleanup和onSubmit之间的状态转换明确

完整示例

以下是整合后的完整组件代码:

"use client";
import { useUI2 } from "ui2-sdk/react";
import { createCerebras } from "@ai-sdk/cerebras";
import { useState } from "react";
import { z } from "zod";

export default function TodoApp() {
  const [todos, setTodos] = useState([]);
  
  let cerebras = createCerebras({ apiKey: "API_KEY" });

  let { inputValue, handleInputChange, handleSubmit } = useUI2({
    model: cerebras("llama-3.3-70b"),
    systemPrompt: "This is a todo app.",
    context: todos.filter(x => !x.preview),
  })
  .addIntent("addTodo", {
    description: "Add a todo",
    parameters: z.object({ name: z.string() }),
    onIntent: ({ parameters, id }) => {
      setTodos((prev) => [
        ...prev,
        { id, name: parameters.name, completed: false, preview: true },
      ]);
    },
    onCleanup: ({ id }) => {
      setTodos((prev) => prev.filter((x) => x.id !== id));
    },
    onSubmit: ({ id }) =>
      setTodos((prev) =>
        prev.map((x) => (x.id === id ? { ...x, preview: false } : x))
      ),
  })
  .addIntent("completeTodo", {
    description: "complete a todo",
    parameters: z.object({ id: z.string() }),
    onIntent: ({ parameters }) => {
      setTodos((prev) =>
        prev.map((x) =>
          x.id === parameters.id
            ? { ...x, preview: true, completed: true }
            : x
        )
      );
    },
    onCleanup: ({ parameters }) => {
      setTodos((prev) =>
        prev.map((x) =>
          x.id === parameters.id
            ? { ...x, preview: false, completed: false }
            : x
        )
      );
    },
    onSubmit: ({ parameters }) =>
      setTodos((prev) =>
        prev.map((x) =>
          x.id === parameters.id
            ? { ...x, preview: false, completed: true }
            : x
        )
      ),
  });

  return (
    <div className="todo-app-container">
      {todos.length ? (
        todos.map((x) => (
          <div key={x.id} className={x.preview ? "opacity-50" : ""}>
            {x.name} - {x.completed ? "Completed" : "Todo"}
          </div>
        ))
      ) : (
        "No todos"
      )}
      <div className="input-container">
        <input
          value={inputValue}
          onChange={(e) => handleInputChange(e.target.value)}
        />
        <button onClick={handleSubmit}>Submit</button>
      </div>
    </div>
  );
}

总结

通过UI2的意图系统,开发者可以:

  1. 以声明式方式定义复杂交互
  2. 统一管理操作的生命周期
  3. 实现可靠的预览-确认流程
  4. 减少状态管理复杂度

这种模式特别适合需要自然语言交互或复杂用户流程的应用场景。掌握意图的使用将显著提升React应用的交互质量和开发效率。

登录后查看全文
热门项目推荐

热门内容推荐

最新内容推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
22
6
docsdocs
OpenHarmony documentation | OpenHarmony开发者文档
Dockerfile
134
1.89 K
nop-entropynop-entropy
Nop Platform 2.0是基于可逆计算理论实现的采用面向语言编程范式的新一代低代码开发平台,包含基于全新原理从零开始研发的GraphQL引擎、ORM引擎、工作流引擎、报表引擎、规则引擎、批处理引引擎等完整设计。nop-entropy是它的后端部分,采用java语言实现,可选择集成Spring框架或者Quarkus框架。中小企业可以免费商用
Java
8
0
ohos_react_nativeohos_react_native
React Native鸿蒙化仓库
C++
193
273
金融AI编程实战金融AI编程实战
为非计算机科班出身 (例如财经类高校金融学院) 同学量身定制,新手友好,让学生以亲身实践开源开发的方式,学会使用计算机自动化自己的科研/创新工作。案例以量化投资为主线,涉及 Bash、Python、SQL、BI、AI 等全技术栈,培养面向未来的数智化人才 (如数据工程师、数据分析师、数据科学家、数据决策者、量化投资人)。
Jupyter Notebook
70
63
openHiTLSopenHiTLS
旨在打造算法先进、性能卓越、高效敏捷、安全可靠的密码套件,通过轻量级、可剪裁的软件技术架构满足各行业不同场景的多样化要求,让密码技术应用更简单,同时探索后量子等先进算法创新实践,构建密码前沿技术底座!
C
395
389
Cangjie-ExamplesCangjie-Examples
本仓将收集和展示高质量的仓颉示例代码,欢迎大家投稿,让全世界看到您的妙趣设计,也让更多人通过您的编码理解和喜爱仓颉语言。
Cangjie
344
1.24 K
RuoYi-Vue3RuoYi-Vue3
🎉 (RuoYi)官方仓库 基于SpringBoot,Spring Security,JWT,Vue3 & Vite、Element Plus 的前后端分离权限管理系统
Vue
916
548
openGauss-serveropenGauss-server
openGauss kernel ~ openGauss is an open source relational database management system
C++
144
189
ShopXO开源商城ShopXO开源商城
🔥🔥🔥ShopXO企业级免费开源商城系统,可视化DIY拖拽装修、包含PC、H5、多端小程序(微信+支付宝+百度+头条&抖音+QQ+快手)、APP、多仓库、多商户、多门店、IM客服、进销存,遵循MIT开源协议发布、基于ThinkPHP8框架研发
JavaScript
96
15