biruk741

react-logging

React/React Native logging templates using DD structured format. For hooks, state, effects, and navigation debugging.

biruk741 0 Updated 3mo ago
GitHub

Install

npx skillscat add biruk741/cc-plugins/react-logging

Install via the SkillsCat registry.

SKILL.md

React & React Native Logging Templates

Helper Function (Add Once Per Session)

// utils/debugLog.ts (temporary - removed after debugging)
declare global {
  interface Window {
    __DD_SESSION__: string;
    __DD_START__: number;
  }
}

export const ddLog = (
  vc: string,
  component: string,
  type: string,
  data: Record<string, unknown>
) => {
  const session = (typeof window !== 'undefined' ? window.__DD_SESSION__ : global.__DD_SESSION__) || 's0';
  const startTime = (typeof window !== 'undefined' ? window.__DD_START__ : global.__DD_START__) || Date.now();
  const ts = Date.now();
  const elapsed = ts - startTime;
  console.log(
    `[DD:${session}:${vc}:${component}:${type}:${ts}]`,
    JSON.stringify({ ts, elapsed, ...data })
  );
};

// Initialize at app entry
if (typeof window !== 'undefined') {
  window.__DD_SESSION__ = 's1';
  window.__DD_START__ = Date.now();
} else {
  (global as any).__DD_SESSION__ = 's1';
  (global as any).__DD_START__ = Date.now();
}

Template: useState Tracking

const [formData, setFormData] = useState<FormData | null>(null);

// Log state value
ddLog('VC1', 'LoginForm', 'STATE', {
  name: 'formData',
  value: formData,
  isNull: formData === null,
});

// Log state updates (wrap setter)
const updateFormData = (newData: FormData) => {
  ddLog('VC1', 'LoginForm', 'STATE', {
    name: 'formData',
    action: 'SET',
    before: formData,
    after: newData,
  });
  setFormData(newData);
};

Template: useEffect Tracking

useEffect(() => {
  ddLog('VC2', 'UserProfile', 'EFFECT', {
    trigger: 'MOUNT_OR_DEPS',
    deps: { userId },
  });

  // ... effect logic ...

  return () => {
    ddLog('VC2', 'UserProfile', 'EFFECT', {
      trigger: 'CLEANUP',
      reason: 'unmount_or_deps_change',
    });
  };
}, [userId]);

Template: Async Operation

const fetchUser = async (id: string) => {
  const opId = Math.random().toString(36).slice(2, 8);

  ddLog('VC3', 'UserService', 'ASYNC', {
    op: 'fetchUser',
    opId,
    phase: 'START',
    input: { id },
  });

  try {
    const result = await api.getUser(id);
    ddLog('VC3', 'UserService', 'ASYNC', {
      op: 'fetchUser',
      opId,
      phase: 'SUCCESS',
      result: result,
    });
    return result;
  } catch (error) {
    ddLog('VC3', 'UserService', 'ASYNC', {
      op: 'fetchUser',
      opId,
      phase: 'ERROR',
      error: error.message,
    });
    throw error;
  }
};

Template: React Navigation (React Native)

import { useFocusEffect } from '@react-navigation/native';

useFocusEffect(
  useCallback(() => {
    ddLog('VC4', 'HomeScreen', 'NAV', {
      event: 'FOCUS',
      params: route.params,
    });

    return () => {
      ddLog('VC4', 'HomeScreen', 'NAV', {
        event: 'BLUR',
      });
    };
  }, [route.params])
);

Template: Component Render

function MyComponent(props: Props) {
  ddLog('VC5', 'MyComponent', 'RENDER', {
    props: props,
    renderCount: useRef(0).current++,
  });

  // ... component logic ...
}