Token导航 LogoToken导航TokenDH.com
前端设计需要联网github未标认证来源可访问clear审计通过

frontend-hooks-creation前端钩子创建

Agent Skill

用于辅助前端页面、组件、样式和交互逻辑的开发与维护。它适合让 Agent 生成或审查 React、Next.js、Vue、Tailwind、CSS 等相关代码,整理组件结构,或定位布局和性能问题。使用时需要结合项目现有设计系统、路由和构建方式,避免只生成孤立片段;涉及页面改动时,应配合本地预览和构建检查确认视觉效果。

总安装

214

周安装

9

GitHub Stars

1

下载量

75
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

3

许可证

MIT

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:frontend-hooks-creation(前端钩子创建)
来源仓库:https://github.com/workshop-ventures/skills
仓库路径:skills/frontend-hooks-creation
安装命令:
npx skills add https://github.com/workshop-ventures/skills --skill frontend-hooks-creation
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。不同来源提供的安装方式可能略有差异;本站展示可直接复制的安装命令,安装前请核对来源页面。

skills.shnpx skills
npx skills add https://github.com/workshop-ventures/skills --skill frontend-hooks-creation

简介

辅助前端组件逻辑封装与自定义钩子开发。

  • 适合 React 项目中状态管理、副作用处理等通用模式抽象。
  • 提供钩子模板生成与最佳实践指导,提升代码复用性。
  • 应适配现有项目依赖与设计系统,避免引入冲突。
  • frontend-hooks-creation 属于前端设计类 Skill,可作为该场景下的辅助能力补充。

SKILL.md

Frontend Hooks Creation

This skill creates React Query hooks for API endpoints using types from @{project}/types following established patterns.

Overview

We use React Query (TanStack Query) for all server state management. Hooks import types from @{project}/types to ensure type safety with the backend.

File Structure

apps/webapp/src/
├── api/
│   ├── client.ts           # Axios instance
│   ├── workflows.ts        # Workflow API functions
│   └── {resource}.ts       # New resource API functions
├── hooks/
│   ├── index.ts            # Re-exports all hooks
│   ├── useWorkflows.ts     # Workflow hooks
│   └── use{Resource}.ts    # New resource hooks
└── lib/
    └── queryClient.ts      # React Query client

Step 1: Create the API Module

First, create apps/webapp/src/api/{resource}.ts:

import { apiClient } from './client';
import type {
  Resource,
  // Query/Params types
  ListResourcesQuery,
  // Body types
  CreateResourceBody,
  UpdateResourceBody,
  // Response types
  ListResourcesResponse,
  GetResourceResponse,
  CreateResourceResponse,
  UpdateResourceResponse,
} from '@{project}/types';

// Re-export types for convenience
export type { CreateResourceBody, UpdateResourceBody, ListResourcesQuery };

// List all resources
export async function listResources(
  params: ListResourcesQuery = {}
): Promise<ListResourcesResponse> {
  const response = await apiClient.get<ListResourcesResponse>('/api/resources', {
    params,
  });
  return response.data;
}

// Get a single resource by ID
export async function getResource(id: string): Promise<Resource> {
  const response = await apiClient.get<GetResourceResponse>(
    `/api/resources/${id}`
  );
  return response.data.result;
}

// Create a new resource
export async function createResource(
  payload: CreateResourceBody
): Promise<Resource> {
  const response = await apiClient.post<CreateResourceResponse>(
    '/api/resources',
    payload
  );
  return response.data.result;
}

// Update a resource
export async function updateResource(
  id: string,
  payload: UpdateResourceBody
): Promise<Resource> {
  const response = await apiClient.put<UpdateResourceResponse>(
    `/api/resources/${id}`,
    payload
  );
  return response.data.result;
}

// Delete a resource
export async function deleteResource(id: string): Promise<void> {
  await apiClient.delete(`/api/resources/${id}`);
}

Step 2: Create the Hooks File

Create apps/webapp/src/hooks/use{Resource}s.ts:

import { useQuery, useMutation } from '@tanstack/react-query';
import type {
  Resource,
  ListResourcesQuery,
  ListResourcesResponse,
  CreateResourceBody,
  UpdateResourceBody,
} from '@{project}/types';
import { queryClient } from '../lib/queryClient';
import * as resourceApi from '../api/resources';

// ============================================
// Query Hooks
// ============================================

// GET /api/resources - List all resources
export const useGetResources = (params: ListResourcesQuery = {}) => {
  return useQuery<ListResourcesResponse>({
    queryKey: ['resources', params],
    queryFn: () => resourceApi.listResources(params),
  });
};

// GET /api/resources/:id - Get a single resource by ID
export const useGetResource = (id: string | null) => {
  return useQuery<Resource>({
    queryKey: ['resource', id],
    queryFn: () => resourceApi.getResource(id!),
    enabled: !!id,
  });
};

// ============================================
// Mutation Hooks
// ============================================

// POST /api/resources - Create a new resource
export const useCreateResource = () => {
  return useMutation({
    mutationFn: (payload: CreateResourceBody) => {
      return resourceApi.createResource(payload);
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['resources'] });
    },
  });
};

// PUT /api/resources/:id - Update a resource
export const useUpdateResource = () => {
  return useMutation({
    mutationFn: (data: { id: string; payload: UpdateResourceBody }) => {
      return resourceApi.updateResource(data.id, data.payload);
    },
    onSuccess: (_, { id }) => {
      queryClient.invalidateQueries({ queryKey: ['resource', id] });
      queryClient.invalidateQueries({ queryKey: ['resources'] });
    },
  });
};

// DELETE /api/resources/:id - Delete a resource
export const useDeleteResource = () => {
  return useMutation({
    mutationFn: (id: string) => {
      return resourceApi.deleteResource(id);
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['resources'] });
    },
  });
};

// ============================================
// Helper Functions
// ============================================

// Invalidate a resource query (useful for real-time updates)
export const invalidateResource = (id: string) => {
  queryClient.invalidateQueries({ queryKey: ['resource', id] });
};

// Invalidate all resources queries
export const invalidateResources = () => {
  queryClient.invalidateQueries({ queryKey: ['resources'] });
};

Step 3: Export from Index

Add to apps/webapp/src/hooks/index.ts:

export * from './useResources';

Hook Naming Conventions

  • Queries: useGet<Resource> or useGet<Resource>s

- useGetWorkflow - single resource by ID - useGetWorkflows - list/collection

  • Mutations: use<Action><Resource>

- useCreateWorkflow - useUpdateWorkflow - useDeleteWorkflow - usePublishWorkflow (action routes)

Query Key Patterns

Use consistent query key patterns for cache invalidation:

// Single resource
queryKey: ['resource', id]

// Collection with filters (include params object)
queryKey: ['resources', params]

// Related/nested resources
queryKey: ['resource-versions', resourceId]

// Invalidate all queries for a resource type
queryClient.invalidateQueries({ queryKey: ['resources'] });

Hook Patterns

Query with Optional ID

For fetching a single resource that may not always have an ID:

export const useGetResource = (id: string | null) => {
  return useQuery<Resource>({
    queryKey: ['resource', id],
    queryFn: () => resourceApi.getResource(id!),
    enabled: !!id, // Only run if id exists
  });
};

Query with Filter Parameters

For list endpoints with optional filters:

export const useGetResources = (params: ListResourcesQuery = {}) => {
  return useQuery<ListResourcesResponse>({
    queryKey: ['resources', params],
    queryFn: () => resourceApi.listResources(params),
  });
};

Mutation with Multiple Parameters

For updates that need both ID and payload:

export const useUpdateResource = () => {
  return useMutation({
    mutationFn: (data: { id: string; payload: UpdateResourceBody }) => {
      return resourceApi.updateResource(data.id, data.payload);
    },
    onSuccess: (_, { id }) => {
      // Invalidate both specific and list queries
      queryClient.invalidateQueries({ queryKey: ['resource', id] });
      queryClient.invalidateQueries({ queryKey: ['resources'] });
    },
  });
};

Action Route Mutation

For non-CRUD actions like publish/archive:

export const usePublishResource = () => {
  return useMutation({
    mutationFn: (id: string) => {
      return resourceApi.publishResource(id);
    },
    onSuccess: (_, id) => {
      queryClient.invalidateQueries({ queryKey: ['resource', id] });
      queryClient.invalidateQueries({ queryKey: ['resources'] });
      // Also invalidate related queries if needed
      queryClient.invalidateQueries({ queryKey: ['resource-versions'] });
    },
  });
};

Using Hooks in Components

import { useGetResources, useDeleteResource } from '../hooks';

function ResourceList() {
  // Fetch data
  const { data, isLoading, error } = useGetResources({ limit: 50 });

  // Mutation
  const deleteResource = useDeleteResource();

  const handleDelete = (id: string) => {
    deleteResource.mutate(id, {
      onSuccess: () => console.log('Deleted!'),
      onError: (err) => console.error(err),
    });
  };

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;

  return (
    <ul>
      {data?.results.map((resource) => (
        <li key={resource.id}>
          {resource.name}
          <button
            onClick={() => handleDelete(resource.id)}
            disabled={deleteResource.isPending}
          >
            Delete
          </button>
        </li>
      ))}
    </ul>
  );
}

Complete Example

See existing implementation:

  • API module: apps/webapp/src/api/workflows.ts
  • Hooks: apps/webapp/src/hooks/useWorkflows.ts

Checklist

After creating hooks for a new resource:

  1. Ensure API schemas exist in libs/types/src/api/{resource}.ts
  2. Create API module in apps/webapp/src/api/{resource}.ts
  3. Create hooks file in apps/webapp/src/hooks/use{Resource}s.ts
  4. Export hooks from apps/webapp/src/hooks/index.ts
  5. Verify TypeScript compilation passes
  6. Test hooks in a component

Important Notes

  1. Always invalidate related queries after mutations to keep data fresh
  2. Use enabled option on queries that depend on parameters that might be null/undefined
  3. Import types from @{project}/types for type safety
  4. Re-export body types from API files for component convenience
  5. Use z.input types for query params (keeps defaults optional)
  6. Use z.infer types for response types (shows final shape after validation)

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

04

需要参考平台分布和安装热度时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

补充不同宿主或平台的使用分布数据

能力 5

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Claude Code

29.06%
按下载量换算22

windsurf

23.28%
按下载量换算17

trae

19.08%
按下载量换算14

OpenCode

15.11%
按下载量换算11

Codex

8.26%
按下载量换算6

Antigravity

4.15%
按下载量换算3

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。

来源信息

继续浏览同类 Skills