Braswelljr Documentation

website·Indexed 30 days ago

https://braswelljr.vercel.app

A collection of technical guides and tutorials covering React (Context, Error Boundaries, createPortal, GSAP, Framer Motion), Go (Context, Error Handling, Goroutines, Channels), TypeScript Generics, and web technologies including HTTP/1.1, HTTP/2, HTTP/3, WebSockets, and Server-Sent Events.

Tokens
21K
Snippets
100
Records
114
Agent score
75%

What's inside Braswelljr

  1. Understand React Context and Prop Drilling

    Context is a React feature used to share state between components without manually passing props through every level of the component tree. This avoids 'Prop Drilling', which occurs when props are passed from a parent to a child, then to a grandchild, and so on. Context is intended for sharing state between closely related components (like siblings or cousins) and is not a direct replacement for global state management libraries like Redux.
  2. Understand React Error Boundary capabilities and limitations

    Error Boundaries are components that catch JavaScript errors in their child component tree, log them, and display a fallback UI. They only catch errors in components below them in the tree; they cannot catch errors thrown within themselves.

    What they catch:

    • Errors during rendering
    • Errors in lifecycle methods
    • Errors in constructors

    What they DO NOT catch:

    • Event handlers (use try/catch instead)
    • Asynchronous code (e.g., setTimeout, promise callbacks)
    • Server-side rendering
    • Errors thrown inside the error boundary component itself
  3. Use the useGSAP hook for React animations

    useGSAP from @gsap/react is the idiomatic way to run GSAP in React. It wraps useLayoutEffect to provide a GSAP context scoped to a container ref, ensuring that all tweens and ScrollTriggers created within it are automatically killed when the component unmounts. It is specifically designed to handle React 18 Strict Mode's double-invocation.
    import { useRef } from 'react';
    import { useGSAP } from '@gsap/react';
    import { gsap } from 'gsap';
    
    export function MyComponent() {
      const containerRef = useRef<HTMLDivElement>(null);
    
      useGSAP(
        () => {
          gsap.to('.box', { opacity: 0 });
        },
        { scope: containerRef } // Scopes all class selectors to this element
      );
    
      return <div ref={containerRef}><div className="box">Hello</div></div>;
    }
  4. Create custom error types

    To provide more structured error data (like field names or error codes), define a custom struct and implement the Error() string method. Use type assertion to access the custom fields of the error.
    type ValidationError struct {
    	Field   string
    	Message string
    }
    
    func (e *ValidationError) Error() string {
    	return fmt.Sprintf("validation failed for field '%s': %s", e.Field, e.Message)
    }
    
    // Usage and Type Assertion
    if validationErr, ok := err.(*ValidationError); ok {
    	fmt.Printf("Field: %s, Message: %s\n", validationErr.Field, validationErr.Message)
    }
  5. Create sequenced animations with gsap.timeline

    Use gsap.timeline() to create a sequence of animations where tweens trigger one after another. You can control the exact start time of each tween using the position parameter to create overlaps or absolute timing.
    const tl = gsap.timeline();
    
    tl.from('#avatar', { opacity: 0, scale: 0.5, duration: 0.4 })
      // starts 0.1s before the previous tween ends
      .from('#name',   { opacity: 0, x: -20 },  '-=0.1')
      // starts 0.15s before the previous tween ends
      .from('#role',   { opacity: 0, x: -20 },  '-=0.15')
      // starts at absolute position 0.8s into the timeline
      .from('#badge',  { opacity: 0, y: 10  },  '0.8')
      // starts immediately after a label called "reveal"
      .from('#cta',    { opacity: 0 },           'reveal')
  6. Install dependencies for motion/react tab animation

    To set up a project with animated tabs using motion/react and Tailwind CSS v4, install the following dependencies. This includes the animation library, Tailwind CSS v4 (next), PostCSS plugins, and the clsx utility for dynamic class merging.
    # Using npm
    npm install motion/react tailwindcss@next @tailwindcss/postcss postcss autoprefixer clsx
    
    # Using pnpm
    pnpm add motion/react tailwindcss@next @tailwindcss/postcss postcss autoprefixer clsx
    
    # Using yarn
    yarn add motion/react tailwindcss@next @tailwindcss/postcss autoprefixer clsx
    
    # Using bun
    bun add motion/react tailwindcss@next @tailwindcss/postcss postcss autoprefixer clsx
  7. Apply best practices for TypeScript Generics

    Follow these guidelines to maintain clean and type-safe generic code:

    1. Prefer functional patterns: Use factory functions and composition instead of class inheritance.
    2. Use descriptive type parameters: Use T for simple cases, but prefer names like TKey, TValue, or TComponent for clarity in complex generics.
    3. Apply constraints: Use the extends keyword to prevent generics from being too permissive and to enforce required properties.
    4. Provide default types: Use the = syntax in generic declarations to provide a fallback type if one isn't specified.
    5. Avoid over-engineering: Only use generics when genuine type flexibility is required.
    // Example of a default type for a generic
    interface Box<T = string> {
      contents: T;
    }
    
    const defaultBox: Box = { contents: 'hello' }; // T defaults to string
  8. Strategically place Error Boundaries in the component tree

    Error boundaries can be placed at different levels of the component tree to isolate failures. Placing them around specific high-risk components (like sidebars, headers, or third-party widgets) ensures that a crash in one section does not bring down the entire application.
    function App() {
      return (
        <div>
          <ErrorBoundary fallback={<div>Header Error</div>}>
            <Header />
          </ErrorBoundary>
    
          <div style={{ display: 'flex' }}>
            <ErrorBoundary fallback={<div>Sidebar Error</div>}>
              <Sidebar />
            </ErrorBoundary>
    
            <ErrorBoundary fallback={<div>Main Content Error</div>}>
              <MainContent />
            </ErrorBoundary>
          </div>
        </div>
      );
    }
  9. Implement basic error handling in functions

    The standard pattern in Go is to return the error as the last return value of a function. The caller should explicitly check if the error is not nil before proceeding with the result.
    func divide(a, b float64) (float64, error) {
    	if b == 0 {
    		return 0, errors.New("division by zero")
    	}
    	return a / b, nil
    }
    
    func main() {
    	result, err := divide(10, 0)
    	if err != nil {
    		fmt.Println("Error:", err)
    		return
    	}
    	fmt.Println("Result:", result)
    }
  10. Choose between custom class boundaries and `react-error-boundary` library

    Decide on an implementation strategy based on your project needs:

    Use a custom class component when:

    • You require zero external dependencies.
    • You need full granular control over the boundary's behavior.

    Use the react-error-boundary library when:

    • You prefer a functional API (using FallbackComponent, onError, and onReset).
    • You need built-in reset support or the useErrorBoundary hook for handling asynchronous errors.

    Important Constraints:

    • There is no built-in Error Boundary component provided by React (including React 19).
    • The boundary implementation must always be a class component (or a library wrapping one).
    • Error boundaries only catch errors in rendering, lifecycle methods, and constructors. They do not catch errors in event handlers or asynchronous code; use try/catch for those cases.
  11. Handle asynchronous errors in React

    Error boundaries do not catch errors in asynchronous code (e.g., fetch calls). You must wrap async operations in try/catch blocks and manage the error state manually within the component to display a fallback UI.
    function AsyncComponent() {
      const [error, setError] = React.useState<Error | null>(null);
      const [data, setData] = React.useState<string | null>(null);
    
      const fetchData = async () => {
        try {
          const response = await fetch('/api/data');
          if (!response.ok) throw new Error('Failed to fetch data');
          const result = await response.json();
          setData(result);
        } catch (err) {
          setError(err as Error);
        }
      };
    
      if (error) return <div>Error: {error.message}</div>;
    
      return (
        <div>
          <button onClick={fetchData}>Fetch Data</button>
          {data && <div>{data}</div>}
        </div>
      );
    }
  12. Implement type-safe property access with keyof constraints

    By combining multiple type parameters and the keyof operator, you can create functions that ensure a key exists on a given object and return the correct type for that specific property.
    function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
      return obj[key];
    }
    
    const user = { name: 'Alice', age: 30 };
    const name = getProperty(user, 'name'); // type is string
    const age = getProperty(user, 'age');   // type is number