react-patterns
GitHub提供 React 组件、Hooks 及 Provider 的编码规范,指导使用 React 19 特性与 Tanstack 生态进行状态管理。同时规范 React Compiler 兼容代码写法,确保自动记忆化正确生效。
Trigger Scenarios
Install
npx skills add TangleML/tangle-ui --skill react-patterns -g -y
SKILL.md
Frontmatter
{
"name": "react-patterns",
"description": "React and React Compiler patterns for this project. Use when writing React components, hooks, providers, or working with React Compiler compatibility."
}
React Patterns
Core Rules
- Use functional components with hooks exclusively (no class components)
- Use proper dependency arrays in useEffect
- Follow the existing component structure
- Use React 19 features and patterns
- Import modules from React:
import module from react. Do not use inlineReact.[module]
Component Structure
// ComponentName/ComponentName.tsx — import directly, no index.ts barrel
interface ComponentNameProps {
...
}
export const ComponentName = ({ }: ComponentNameProps) => {
...
return (
...
);
};
Custom Hooks
- Prefix with
use - Return objects for multiple values, not arrays
- Use proper TypeScript return types
- Follow existing patterns in
src/hooks/
Provider Pattern
const Context = createContext<ContextType | null>(null);
export const Provider = ({ children }: { children: ReactNode }) => {
...
return <Context.Provider value={value}>{children}</Context.Provider>;
};
export const useContext = () => {
const context = useContext(Context);
if (!context) throw new Error('useContext must be used within Provider');
return context;
};
State Management
- Use Tanstack Query for server state
- Use Tanstack Router for routing
- Use React hooks for local component state
- Use Context providers for app-wide state (see existing providers in
src/providers/) - Use
useRequiredContextto simplify context usage and avoid null checks
React Compiler
This project uses the React Compiler for automatic memoization. Files/directories are incrementally adopted in react-compiler.config.js.
Writing React Compiler Compatible Code
For new files, ensure they follow React Compiler rules from the start:
-
Don't mutate values during render
// Bad - mutating during render const items = props.items; items.push(newItem); // Good - create new reference const items = [...props.items, newItem]; -
Don't read/write refs during render
// Bad - reading ref during render const value = myRef.current; return <div>{value}</div>; // Good - read refs in effects or callbacks useEffect(() => { const value = myRef.current; }, []); -
Follow Rules of Hooks strictly - no conditional hooks, no hooks in loops, proper dependency arrays
-
Avoid patterns the compiler can't optimize
- Don't spread props with
{...props}unnecessarily - Avoid dynamic property access on objects when possible
- Keep component logic predictable
- Don't spread props with
Adding Files to React Compiler
When a file is added to react-compiler.config.js:
- Remove unnecessary
useCallbackanduseMemo(compiler handles this) - Verify no compiler violations with
pnpm run validate - Test the component still works correctly
- Consolidate entries by folder when all files in a directory are compiler-enabled (e.g., use
/path/to/folderinstead of listing each file individually)
React Compiler Config Structure
Files are organized by cleanup effort in react-compiler.config.js:
- Top section: Already enabled directories/files
- Middle: Ready to enable (0 useCallback/useMemo)
- Bottom (commented): Need cleanup before enabling
Performance
- Do not use
useMemo,useCallback, ormemomanually — the React Compiler handles memoization automatically - If you encounter existing
useMemo/useCallback/memoin a file, remove them when the file is enabled inreact-compiler.config.js - Lazy load heavy components when possible
- Follow existing patterns for optimization
Version History
- d7768e8 Current 2026-09-02 20:59


