react

<core_principles>

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "react" with this command: npx skills add d-kimuson/dotfiles/d-kimuson-dotfiles-react

<core_principles>

Core Principles

  1. Minimize useEffect Usage

Think harder before adding useEffect. Most scenarios have better alternatives:

<when_not_to_use_effect>

When NOT to Use useEffect

Data transformation for rendering:

  • ❌ Don't: Use Effect to compute derived state

  • ✅ Do: Calculate during render at top level

// ❌ Bad: Cascading updates const [filteredItems, setFilteredItems] = useState<Item[]>([]); useEffect(() => { setFilteredItems(items.filter(item => item.active)); }, [items]);

// ✅ Good: Direct computation const filteredItems = items.filter(item => item.active);

Handling user events:

  • ❌ Don't: Use Effect to respond to user actions

  • ✅ Do: Handle logic in event handlers

// ❌ Bad: Lost interaction context useEffect(() => { if (buttonClicked) { submitForm(); } }, [buttonClicked]);

// ✅ Good: Explicit intent const handleSubmit = () => { submitForm(); };

Caching expensive computations:

  • ❌ Don't: Store computed results in state via Effects

  • ✅ Do: Use useMemo

// ❌ Bad: Manual memoization const [expensiveResult, setExpensiveResult] = useState<Result | null>(null); useEffect(() => { setExpensiveResult(computeExpensiveValue(data)); }, [data]);

// ✅ Good: useMemo const expensiveResult = useMemo(() => computeExpensiveValue(data), [data]);

Resetting state on prop changes:

  • ❌ Don't: Use Effect to reset state

  • ✅ Do: Use key prop to force remount

// ❌ Bad: Manual synchronization useEffect(() => { setLocalState(defaultValue); }, [userId]);

// ✅ Good: Key-based reset <Profile key={userId} userId={userId} />

</when_not_to_use_effect>

<legitimate_use_cases>

Legitimate useEffect Use Cases

Only use Effects for:

  • Synchronizing with external systems (browser APIs, third-party widgets)

  • Data fetching with proper cleanup (avoid race conditions)

  • Subscriptions (prefer useSyncExternalStore when possible)

Pattern for data fetching (if not using query client):

useEffect(() => { let ignore = false;

async function fetchData() { const result = await api.getData(); if (!ignore) { setData(result); } }

fetchData(); return () => { ignore = true; }; // Cleanup to prevent race conditions }, [dependency]);

</legitimate_use_cases> </core_principles>

<component_definition>

  1. Component Definition Style

Always use FC type annotation:

import { FC, PropsWithChildren } from 'react';

// For components without children type ButtonProps { label: string; onClick: () => void; }

const Button: FC<ButtonProps> = ({ label, onClick }) => { return <button onClick={onClick}>{label}</button>; };

// For components that accept children type CardProps { title: string; }

const Card: FC<PropsWithChildren<CardProps>> = ({ title, children }) => { return ( <div> <h2>{title}</h2> <div>{children}</div> </div> ); };

Never use function declaration syntax:

// ❌ Bad: Avoid this style function MyComponent(props: Props) { return <div />; }

</component_definition>

<api_requests>

  1. API Request Handling

Never use fetch directly in components. Always use the project's query client.

<detection_workflow>

Detection Workflow

Check project dependencies in package.json:

  • @apollo/client → Use Apollo Client hooks

  • @tanstack/react-query → Use Tanstack Query hooks

  • swr → Use SWR hooks

Search for existing usage patterns:

  • Look for useQuery , useMutation , useSWR , useApolloClient in codebase

  • Follow established patterns for consistency

Apply appropriate client:

<apollo_client> Apollo Client (GraphQL):

import { useQuery, useMutation, gql } from '@apollo/client';

const GET_USER = gql query GetUser($id: ID!) { user(id: $id) { id name email } };

const UserProfile: FC<{ userId: string }> = ({ userId }) => { const { data, loading, error } = useQuery(GET_USER, { variables: { id: userId }, });

if (loading) return <Spinner />; if (error) return <ErrorMessage error={error} />;

return <div>{data.user.name}</div>; };

// Mutations const UPDATE_USER = gql mutation UpdateUser($id: ID!, $name: String!) { updateUser(id: $id, name: $name) { id name } };

const EditForm: FC = () => { const [updateUser, { loading }] = useMutation(UPDATE_USER);

const handleSubmit = async (values: FormValues) => { await updateUser({ variables: { id: values.id, name: values.name } }); };

return <form onSubmit={handleSubmit}>...</form>; };

</apollo_client>

<tanstack_query> Tanstack Query (REST):

import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';

const UserProfile: FC<{ userId: string }> = ({ userId }) => { const { data, isLoading, error } = useQuery({ queryKey: ['user', userId], queryFn: () => api.getUser(userId), });

if (isLoading) return <Spinner />; if (error) return <ErrorMessage error={error} />;

return <div>{data.name}</div>; };

// Mutations with cache invalidation const EditForm: FC = () => { const queryClient = useQueryClient();

const mutation = useMutation({ mutationFn: (values: FormValues) => api.updateUser(values), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['user'] }); }, });

const handleSubmit = (values: FormValues) => { mutation.mutate(values); };

return <form onSubmit={handleSubmit}>...</form>; };

</tanstack_query>

const UserProfile: FC<{ userId: string }> = ({ userId }) => { const { data, error, isLoading } = useSWR( /api/users/${userId} , fetcher );

if (isLoading) return ; if (error) return ;

return {data.name}; };

// Mutations const EditForm: FC = () => { const { trigger, isMutating } = useSWRMutation( '/api/users', updateUser );

const handleSubmit = async (values: FormValues) => { await trigger(values); };

return ...; };

</swr> </detection_workflow>

Benefits of query clients:

  • Automatic caching and deduplication
  • Loading/error state management
  • Race condition handling
  • Cache invalidation and refetching
  • Optimistic updates support </api_requests> </core_principles>

<workflow>

Implementation Workflow

  1. Before writing component:

    • Identify data dependencies and state requirements
    • Think harder: Can state be derived instead of stored?
    • Plan event handlers before considering Effects
  2. During implementation:

    • Define component with FC type annotation
    • Calculate derived values at top level
    • Use useMemo only for expensive computations
    • Handle user interactions in event handlers
    • Use query client hooks for API requests
  3. Effect review checklist:

    • Is this synchronizing with an external system?
    • Could this be a calculated value instead?
    • Should this be in an event handler?
    • Am I using the right hook (useMemo, key prop)?
    • If data fetching, is query client available?
  4. If Effect is necessary:

    • Document why Effect is required
    • Implement proper cleanup to prevent memory leaks
    • Handle race conditions for async operations </workflow>

<anti_patterns>

Anti-Patterns to Avoid

Chaining Effects:

// Bad: Effects triggering each other
useEffect(() => setB(a), [a]);
useEffect(() => setC(b), [b]);

// Good: Direct computation or single event handler
const b = computeB(a);
const c = computeC(b);

❌ Effect-based initialization:

// Bad: One-time initialization in Effect
useEffect(() => {
  setData(expensiveInit());
}, []);

// Good: useState with initializer
const [data] = useState(() => expensiveInit());

❌ Direct fetch calls:

// Bad: Manual fetch in component
useEffect(() => {
  fetch('/api/data').then(res => res.json()).then(setData);
}, []);

// Good: Use query client
const { data } = useQuery({ queryKey: ['data'], queryFn: fetchData });

&#x3C;/anti_patterns>

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

react

No summary provided by upstream source.

Repository SourceNeeds Review
General

article-writing

No summary provided by upstream source.

Repository SourceNeeds Review
General

prompt-engineering

No summary provided by upstream source.

Repository SourceNeeds Review
General

skill-installer

No summary provided by upstream source.

Repository SourceNeeds Review