搜索

PythonReactSEOPDF
GitHub Skill

react

Core React patterns, hooks, state management, and best practices. Trigger: When working with React components, hooks, or state management.

333-333-333☆ 0 仓库 Stars0 仓库 Forks

安装与使用

请根据来源仓库和你的 AI 工具说明安装此技能。先阅读技能文件和依赖要求,再添加到工作流。

查看来源 ↗使用指南

技能说明

When to Use

  • Creating or refactoring React components
  • Implementing custom hooks
  • Managing state (local, context, or global)
  • Optimizing component performance
  • Handling side effects

Critical Patterns

Functional Components (Always)

// Good: Functional component with hooks
export function UserProfile({ userId }) {
  const [user, setUser] = useState(null);
  
  useEffect(() => {
    fetchUser(userId).then(setUser);
  }, [userId]);

  if (!user) return <Loading />;
  return <ProfileCard user={user} />;
}

// Bad: Class components (legacy)
class UserProfile extends React.Component { /* ... */ }

Component Organization

// Single component file structure
import { useState, useEffect, useCallback } from 'react';

// 1. Types/interfaces (if TypeScript)
// 2. Component
export function MyComponent({ prop1, prop2, onAction }) {
  // 3. Hooks (state, refs, context, custom)
  const [state, setState] = useState(null);
  const ref = useRef(null);
  
  // 4. Derived state / memos
  const computed = useMemo(() => /* ... */, [dep]);
  
  // 5. Callbacks
  const handleClick = useCallback(() => {
    onAction(state);
  }, [state, onAction]);
  
  // 6. Effects
  useEffect(() => {
    // setup
    return () => { /* cleanup */ };
  }, []);

  // 7. Early returns (loading, error)
  if (!state) return null;

  // 8. Render
  return <View />;
}

// 9. Styles (if colocated)

Hooks

useState

// Simple state
const [count, setCount] = useState(0);

// Object state (always spread)
const [form, setForm] = useState({ name: '', email: '' });
setForm(prev => ({ ...prev, name: 'John' }));

// Lazy initialization (expensive computation)
const [data, setData] = useState(() => computeExpensiveValue());

useEffect

// Mount only
useEffect(() => {
  init();
}, []);

// With cleanup
useEffect(() => {
  const subscription = subscribe();
  return () => subscription.unsubscribe();
}, []);

// With dependencies
useEffect(() => {
  fetchData(id);
}, [id]);

// NEVER: missing dependencies or lying about them
useEffect(() => {
  doSomething(value); // ESLint will warn
}, []); // Bad: value is used but not listed

useCallback

// Memoize functions passed to children
const handlePress = useCallback(() => {
  doSomething(id);
}, [id]);

// Without useCallback: new function every render = child re-renders
<ChildComponent onPress={() => doSomething(id)} /> // Bad
<ChildComponent onPress={handlePress} /> // Good

useMemo

// Expensive computations
const sortedList = useMemo(() => {
  return items.sort((a, b) => a.name.localeCompare(b.name));
}, [items]);

// Object references for dependencies
const config = useMemo(() => ({
  threshold: 0.5,
  maxItems: 10,
}), []);

useRef

// DOM/component references
const inputRef = useRef(null);
inputRef.current?.focus();

// Mutable values that don't trigger re-render
const renderCount = useRef(0);
renderCount.current += 1;

// Previous value pattern
const prevValue = useRef(value);
useEffect(() => {
  prevValue.current = value;
}, [value]);

useContext

// Create context
const ThemeContext = createContext(null);

// Provider
export function ThemeProvider({ children }) {
  const [theme, setTheme] = useState('light');
  const value = useMemo(() => ({ theme, setTheme }), [theme]);
  
  return (
    <ThemeContext.Provider value={value}>
      {children}
    </ThemeContext.Provider>
  );
}

// Custom hook (preferred over direct useContext)
export function useTheme() {
  const context = useContext(ThemeContext);
  if (!context) {
    throw new Error('useTheme must be used within ThemeProvider');
  }
  return context;
}

Custom Hooks

Pattern

// hooks/useAsync.js
export function useAsync(asyncFn, deps = []) {
  const [state, setState] = useState({
    data: null,
    loading: true,
    error: null,
  });

  useEffect(() => {
    setState(s => ({ ...s, loading: true }));
    
    asyncFn()
      .then(data => setState({ data, loading: false, error: null }))
      .catch(error => setState({ data: null, loading: false, error }));
  }, deps);

  return state;
}

// Usage
const { data, loading, error } = useAsync(() => fetchUser(id), [id]);

Naming Convention

Hook Purpose
useUser Fetch/manage user data
useToggle Boolean toggle state
useDebounce Debounced value
useLocalStorage Persist to storage
useVoiceCommands Domain-specific hook

State Management Decision Tree

Is state used by one component only?
  → useState

Is state shared by parent-child?
  → Props + callbacks (lift state up)

Is state shared by siblings?
  → Lift to common parent, or Context

Is state global / deeply nested consumers?
  → Context + useReducer, or Zustand/Jotai

Is state server data?
  → React Query / TanStack Query

Performance

React.memo

// Wrap pure components that receive same props often
export const ExpensiveList = React.memo(function ExpensiveList({ items }) {
  return items.map(item => <Item key={item.id} {...item} />);
});

// Custom comparison
export const Component = React.memo(MyComponent, (prevProps, nextProps) => {
  return prevProps.id === nextProps.id;
});

Avoid Re-renders

// Bad: inline objects create new reference every render
<Component style={{ flex: 1 }} />
<Component config={{ theme: 'dark' }} />

// Good: stable references
const style = useMemo(() => ({ flex: 1 }), []);
const config = useMemo(() => ({ theme }), [theme]);

Code Splitting

// Lazy load heavy components
const HeavyChart = lazy(() => import('./HeavyChart'));

function Dashboard() {
  return (
    <Suspense fallback={<Loading />}>
      <HeavyChart />
    </Suspense>
  );
}

Anti-patterns

Don't Do Why
Mutate state directly Use setState with new object React won't detect changes
useEffect for derived state useMemo Unnecessary render cycle
Fetch in useEffect without cleanup Use abort controller or React Query Race conditions
Index as key in dynamic lists Unique stable ID Causes bugs on reorder
Prop drilling 5+ levels Context or composition Hard to maintain
God components (500+ lines) Split into smaller components Unreadable

File Naming

Type Convention Example
Components PascalCase UserProfile.jsx
Hooks camelCase with use prefix useAuth.js
Utils camelCase formatDate.js
Constants UPPER_SNAKE or camelCase API_URL or routes.js
Types PascalCase User.ts

使用示例

查看来源仓库中的使用示例与配置说明。

查看来源 ↗

来源历史

收录时间
2026-01-20
索引更新时间
2026-01-26
Branch
main

收录与同步日期属于本站记录。源码修改历史请查看来源仓库。

GitHub ↗

chat Comments (0)

chat_bubble_outline

No comments yet. Be the first to share your thoughts!