跳到正文
cccskills
免费在 GitHub 公开中文介绍

react

用于编写 React 和 TSX 界面,按项目现有规范选择组件与样式、安排状态和布局,并判断是否需要使用记忆化优化。

原文查看原文说明

Use for TSX components, UI libraries, styling, state locality, layout, render performance and memoization.

lobehub/lobehub星标 83,504(GitHub 83,504 + cccskills 0)

实测评分 未实测

查看安装方法

适用场景

  • 用现有界面组件实现页面
  • 规划样式迁移
  • 确定状态由哪个组件管理
  • 判断是否需要记忆化

中文介绍

功能

这份指南帮助你使用 React 或 TSX 编写界面,并遵循项目已有的界面库和样式规范。它说明如何选择组件、组织样式与布局,以及把状态放在最小且合适的组件中。指南还介绍了将样式迁移到 StyleX 的做法,以及如何检查迁移前后的样式差异。对于渲染性能,建议先确认 memo、useMemo 或 useCallback 能避免哪些实际工作,再决定是否使用。只有在复用或更新边界等原因明确时,才拆分组件。

适用场景

创建需要符合现有界面模式的组件时,可以参考本指南。状态应该放在哪里,或某处渲染较慢、需要调查时也适用。复杂布局可查看 Flexbox 和 Center 的用法。

使用示例

  • “请使用现有界面组件和样式规范实现这个 TSX 页面。”
  • “请判断这份状态应由父组件还是子组件管理,并整理组件拆分边界。”
  • “请检查这次重新渲染的更新路径,判断是否需要记忆化。”

注意事项

组件选择和迁移步骤依据 @lobehub/ui、StyleX 等项目专用配置。详细布局示例请参阅 references/layout-kit.md。

本介绍由 AI(OpenAI Codex)根据公开的 SKILL.md 撰写。准确的规格请查看下方原文。

文档检查

AI 根据 SKILL.md 的内容检查了需要注意的操作和使用前提。评分只依据实际运行的结果(实测对比)。

安全性发送数据、删除文件、执行命令等是否有说明
B部分不足迁移检查会使用 `git stash`,但相关防护说明有限。
安装难易度所需工具和 API 密钥是否少且有说明
B部分不足资料依赖 Bun、StyleX 和项目专用界面库,但未提供安装步骤。

不计入评分。 由 AI(OpenAI Codex)于 2026年10月26日 评估。仅供参考,安装前请同时查看原文。

如果您认为评估有误,请申请复核

请写明哪一项有误以及原因。无需登录。我们会对照 SKILL.md 重新评估,并在此处更新结果。

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

包含的文件(2)

  • SKILL.md11.6 KB
  • references/layout-kit.md2.3 KB

SKILL.md(原文)

安装前可以查看交给 AI 代理的指令内容。

React Component Writing Guide

Styling

ScenarioApproach
Files already on StyleX, and new SPA stylesstylex.create + @lobehub/ui/stylex/cssVar.stylex / @lobehub/ui/stylex/media.stylex. The SPA compiler is plugins/vite/stylex.ts (@stylexjs/unplugin, prefix lh). Do not copy those token modules into the app.
Existing styles not yet migratedcreateStaticStyles + cssVar.* (zero-runtime, module-level)
Simple one-offInline style attribute
Truly dynamic (JS color fns like readableColor/chroma)createStyles + token — last resort

StyleX

  • New code may not import createStaticStyles / createStyles / css / keyframes / createGlobalStyle / injectGlobal from @lobehub/ui (stylex-migration/no-emotion-styles). Files still on them are listed in scripts/stylexMigration/legacyFiles.json; after migrating one, run bun run stylex:migration --prune-legacy. Never add entries.
  • Migrate a whole file at once. StyleX longhand rules carry raised specificity (.x:not(#\#)) and beat emotion classes on the same element, but StyleX shorthand rules do not, so a half-migrated element resolves by property.
  • Element that also forwards a caller's className / style: {...sx([styles.root, active && styles.active], className, style)} from @/styles/sx. Spreading stylex.props next to className fails @stylexjs/no-conflicting-props.
  • Component that lets callers restyle it: take xstyle?: StyleXStyles and pass it last in the sx / stylex.props array. A plain className from outside cannot override StyleX rules. Passing a class to @lobehub/ui components (className, classNames) works, because lobe-ui CSS sits in @layer lobe-ui.
  • Values follow @stylexjs/valid-styles: no multi-value shorthands (margin: '0 8px' → marginBlock / marginInline), and string flex (flex: '1').
  • background, animation, border and border{Top,Right,Bottom,Left} shorthands compile to no class at all, whatever the value (border: 'none' included), without an error. Write longhands: backgroundColor (plus backgroundImage: 'none' when replacing a background shorthand), animationName / animationDuration / …, borderWidth / borderStyle / borderColor.
  • Check a migration in dev with the DevDock snapshot helper: on the migrated page run __lobeStyleSnapshot.capture('<name>', '<root selector>'), swap the files back (git stash push -- <path>), reload, run __lobeStyleSnapshot.compare('<name>'), then git stash pop. Each pair reads [captured, current], here [migrated, original]. It lists elements and ::before / ::after whose tracked computed styles, box (relative to the root) or text differ; an empty list means those match, not that hover, focus or closed dialogs were checked, so open each state you migrated and compare it too. Keep the window size, scroll everything under the root back to the start, and move the pointer off the compared area.
  • bun run stylex:migration --list <A|B|C|D> lists files by how hard they are to move: A flat, B self pseudo-classes, C descendant / ancestor coupling (use stylex.defaultMarker() + stylex.when.ancestor() or xstyle), D tag / third-party DOM selectors (scoped plain CSS).

Component Priority

  1. src/components — project-specific reusable components
  2. @lobehub/ui/base-ui — headless primitives. If the component lives here, use it. Do NOT import the same-named root export.
  3. @lobehub/ui — higher-level / antd-wrapping components (only when no base-ui equivalent)
  4. antd — only when neither base-ui nor @lobehub/ui root provides it
  5. Custom implementation — true last resort

If unsure about available components, search existing code or check node_modules/@lobehub/ui/es/index.mjs and node_modules/@lobehub/ui/es/base-ui/.

@lobehub/ui/base-ui — always prefer for these

ComponentImport
Alert (+ AlertProps)import { Alert, type AlertProps } from '@lobehub/ui/base-ui';
Select (+ SelectProps, SelectOption)import { Select } from '@lobehub/ui/base-ui';
Modal (imperative API)import { createModal, confirmModal, useModalContext, type ModalInstance } from '@lobehub/ui/base-ui';
DropdownMenuimport { DropdownMenu } from '@lobehub/ui/base-ui';
ContextMenuimport { ContextMenu } from '@lobehub/ui/base-ui';
Popoverimport { Popover } from '@lobehub/ui/base-ui';
ScrollAreaimport { ScrollArea } from '@lobehub/ui/base-ui';
Switchimport { Switch } from '@lobehub/ui/base-ui';
Toastimport { Toast } from '@lobehub/ui/base-ui';
FloatingSheetimport { FloatingSheet } from '@lobehub/ui/base-ui';
Drawerimport { Drawer } from '@lobehub/ui/base-ui';

For Modal specifically, see the dedicated modal skill — use the imperative createModal({ content: … }) pattern over the legacy <Modal open … /> declarative pattern. base-ui has its own ModalHost already mounted in SPAGlobalProvider.

Common slip: import { Select } from '@lobehub/ui' looks fine but it's the antd-backed Select. Use base-ui Select. Same for Modal, DropdownMenu, etc.

@lobehub/ui root — use when base-ui has no equivalent

CategoryComponents
GeneralActionIcon, ActionIconGroup, Block, Button, Icon
Data DisplayAvatar, Collapse, Empty, Highlighter, Markdown, Tag, Tooltip
Data EntryCodeEditor, CopyButton, EditableText, Form, Input, InputPassword, SearchBar, TextArea
LayoutCenter, DraggablePanel, Flexbox, Grid, Header, MaskShadow
NavigationBurger, Menu, SideNav, Tabs

State

Keep transient state in its smallest useful owner. Extract a custom hook when state transitions and handlers obscure rendering or form a reusable unit; do not extract solely because a component has a particular number of hooks.

Split a component only to establish a real state, reuse, render-update, or mountable-capability boundary. Do not split solely to make files smaller; when a file reaches the 1200-line limit in source-layout, find one of these boundaries rather than cutting at a line count. Decomposing a heavy domain feature into host-assembled atoms is owned by compose-atoms.

Popover Exits

An action inside popover content that leaves the popover must close it, or the popover stays over the destination (for example, a plan badge in the user panel navigating to /settings/plans).

  • Navigation: a host whose content links or navigates keeps open state, calls useCloseOnNavigate(open, () => setOpen(false)) from @/hooks/useCloseOnNavigate, and passes the returned key to its Popover. This covers links added later, including links from other files. The key matters when navigation hides the host in an <Activity> (the home sidebar): a hidden tree sets up no new effects, so the base-ui popup never finishes its exit animation and stays on screen until a remount removes it.
  • Modal handoff or a final pick: call usePopoverContext().close() (or the host's setter) before opening the modal or after the pick, as NavPanel/switcher/SwitcherMenu.tsx does. Content rendered outside a popover cannot use the context, because its default close throws in development.
  • A confirm step whose result appears in the same popover, such as the share-link privacy confirm, keeps it open.

Render Performance and Memoization

Treat memo, useMemo, and useCallback as opt-in optimizations, not default component wrappers. Before adding one, identify the actual rerender boundary and prefer structural fixes:

  1. Split at the update boundary.
  2. Move transient state to its smallest owner.
  3. Use narrow Zustand selectors and avoid broad subscriptions.

Do not memoize prop-free or trivially rendered components, or a component that normally receives new objects, arrays, functions, or JSX children. Do not use memoization to compensate for state held too high in the tree.

Use memoization only when the subtree is demonstrably expensive or frequently repeated, its relevant inputs are stable during normal parent renders, and profiling or a concrete render-path analysis identifies the avoided work. State that reason in the implementation summary or PR.

Layout

Use Flexbox and Center from @lobehub/ui. See references/layout-kit.md for full props and examples.

  • Use gap instead of margin for spacing between flex children
  • Use flex={1} to fill available space
  • Nest Flexbox for complex layouts; set overflow: 'auto' for scrollable regions

Related Skills

  • ux: loading visuals (scenario → loader table in references/feedback.md §4.1) and user-facing interaction design.
  • modal: imperative base-ui modal patterns.
  • spa-routes: SPA navigation, route ownership, router configuration, and .desktop variants.
  • compose-atoms: split a heavy domain feature into mountable capability atoms; each host imports only what it mounts.
  • zustand: store structure and selector conventions.

评价

还没有评价。欢迎分享你的使用感受。

评论

无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。

还没有评论。来写第一条吧。

提交后会立即公开。请勿填写邮箱、电话等个人信息。URL 最多 2 个。

0 / 1000 字

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

同一仓库的技能

acceptance

免费有简介

通过实际操作产品验证交付内容,记录用户可查看的证据,并发布验收报告。可检查已有验证计划或创建检查项,选择合适的操作界面,并使用 `lh` CLI 发布结果。

  • 实际检查更改后的产品行为
  • 收集截图或其他验证证据
  • 编写验证计划和报告
lobehub/lobehub8.4万2026年10月26日 更新

add-model-provider

免费有简介

本技能指导在 LobeHub 中接入 AI 模型提供商,涵盖运行时、模型信息、设置、品牌展示、文档和验收,并帮助判断新增模型是否需要新的提供商集成。

  • 为 LobeHub 接入新的 AI 模型提供商
  • 更新提供商设置说明或介绍
  • 判断添加模型是否需要新的提供商集成
lobehub/lobehub8.4万2026年10月26日 更新

add-setting-env

免费有简介

本技能指导如何用服务器端环境变量设置用户偏好默认值,涵盖变量校验、服务器配置、写入用户状态,以及更新 `.env.example` 和自托管文档。

  • 通过环境变量设置用户偏好默认值
  • 将设置接入服务器配置和用户状态
  • 更新环境变量示例及文档
lobehub/lobehub8.4万2026年10月26日 更新

agent-runtime-hooks

免费有简介

说明如何在智能体执行步骤、工具调用、人工审批、上下文压缩和子智能体调用时注册钩子。钩子可观察事件、模拟本地工具结果,也可通过 Webhook 按配置策略允许或拒绝工具调用。

  • 记录智能体步骤和错误
  • 测试时模拟工具结果
  • 通过 Webhook 允许或拒绝工具调用
lobehub/lobehub8.4万2026年10月26日 更新

agent-signal

免费有简介

此技能用于为智能体设计事件驱动的后台工作流,划分来源、信号、动作和策略的职责,并处理异步交接、去重、执行范围、完成记录与运行观测。

  • 添加事件触发的后台任务
  • 将工作移出对话请求
  • 防止动作重复执行
lobehub/lobehub8.4万2026年10月26日 更新

agent-testing-bot

免费有简介

本技能在 macOS 桌面聊天应用中测试机器人频道:打开应用、进入频道或联系人、发送消息、等待回复并截图。支持 Discord、Slack、Telegram、微信、飞书和 QQ;iMessage 使用 BlueBubbles 桥接。

  • 检查真实 Discord 频道中的机器人回复
  • 测试 Slack 或 Telegram 的对话流程
  • 记录 macOS 应用中的操作结果
lobehub/lobehub8.4万2026年10月26日 更新

查看 lobehub 的全部技能

报告此技能的问题