opik-frontend
1
总安装量
1
周安装量
#45192
全站排名
安装命令
npx skills add https://smithery.ai
Agent 安装分布
cursor
1
Skill 文档
Opik Frontend
Architecture Decisions
- Routing: TanStack Router (file-based)
- Data fetching: TanStack Query (never raw fetch/useEffect)
- State: Zustand for global, React state for local
- Components: shadcn/ui + Radix UI base
- Forms: React Hook Form + Zod validation
Critical Gotchas
Never useEffect for Data Fetching
// â BAD
useEffect(() => {
fetch('/api/data').then(setData);
}, []);
// â
GOOD
const { data } = useQuery({
queryKey: ['data'],
queryFn: fetchData,
});
Selective Memoization
// â
USE useMemo for: complex computations, large data transforms
const filtered = useMemo(() =>
data.filter(x => x.status === 'active').map(transform),
[data]
);
// â
USE useCallback for: functions passed to children
const handleClick = useCallback(() => doSomething(id), [id]);
// â DON'T memoize: simple values, primitives, local functions
const name = data?.name ?? ''; // No useMemo needed
Zustand Selectors
// â
GOOD - specific selector
const selectedEntity = useEntityStore(state => state.selectedEntity);
// â BAD - selecting entire store causes re-renders
const { selectedEntity, filters } = useEntityStore();
Layer Architecture
ui â shared â pages-shared â pages (one-way only)
- No circular dependencies
- No cross-page imports
- After modifying imports:
npm run deps:validate
State Location Decisions
- URL state: filters, pagination, selected items
- Zustand: user preferences, cross-component state
- React state: form inputs, UI toggles
Component Structure
const Component: React.FC<Props> = ({ prop }) => {
// 1. State hooks
// 2. Queries/mutations
// 3. Memoization (only when needed)
// 4. Event handlers
if (isLoading) return <Loader />;
if (error) return <ErrorComponent />;
return <div>...</div>;
};
Query Patterns
// Query with params
const { data } = useQuery({
queryKey: [ENTITY_KEY, params],
queryFn: (context) => fetchEntity(context, params),
});
// Mutation with invalidation
const mutation = useMutation({
mutationFn: updateEntity,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: [ENTITY_KEY] });
},
});
Reference Files
- forms.md – React Hook Form + Zod patterns
- ui-components.md – Button variants, typography, dark theme
- responsive-design.md – Tailwind breakpoints vs useIsPhone
- testing.md – When to test, Vitest patterns
- code-quality.md – Lodash imports, naming, deps:validate
- performance.md – Bundle optimization, rendering, memoization