Snippets

codeIcon imguseWindowSize

To get the current size of the browser window. It returns an object containing the window's width and height. If executed server-side, the value of width and height will be undefined.

                
                   import { useState, useEffect } from 'react'
                    // Usage
                    const App = () => {
                      const size = useWindowSize();
                      return (
                        <div>
                          {DEVICE_SIZES.width}px / {size.height}px
                        </div>
                      );
                    }
                     
 // Hook
 const useWindowSize = () => {
  // Initialize state with undefined width/height so server and 
  // and client renders match 
    const [windowSize, setWindowSize] = useState({
      width: undefined,
      height: undefined,
    });

    useEffect(() => {
      // Handler to call on window resize
    function handleResize() {
      setWindowSize({
        width: window.innerWidth,
        height: window.innerHeight,
      })
    }

    // Add event listener
    window.addEventListener('resize', handleResize);
    
    // Call right away
    handleResize();
    
    // Cleanup
    return () => window.removeEventListener('resize', handleResize)
    
    },[]) //only runs on mount

    return windowSize;

  }
     

codeIcon imgReact Sticky Hook - Ref

A React hook for observing position: sticky state on refs. useSticky returns a pair of values: the ref to observe and the current sticky state of the ref.

                
  import { useEffect, useRef, useState } from "react";

  /**
    * Returns a ref, and a stateful value bound to the ref
    * @returns [Any, Boolean]
    * //robinjohnson repo
    */
  

  export function useSticky() {
    const stickyRef = useRef(null);
    const [sticky, setSticky] = useState(false);
    const eventsToBind = [
      [document, "scroll"],
      [window, "resize"],
      [window, "orientationchange"]
    ]; 
     
  useEffect(() => {
    // Observe when ref enters or leaves sticky state
    // rAF https://stackoverflow.com/questions/41740082/scroll-events-requestanimationframe-vs-requestidlecallback-vs-passive-event-lis
    function observe() {
      const refPageOffset = stickyRef.current.getBoundingClientRect().top;
      const stickyOffset = parseInt(getComputedStyle(stickyRef.current).top);
      const stickyActive = refPageOffset <= stickyOffset;

      if (stickyActive && !sticky) setSticky(true);
      else if (!stickyActive && sticky) setSticky(false);
    }

    observe();

    // Bind events
    eventsToBind.forEach(eventPair => {
      eventPair[0].addEventListener(eventPair[1], observe);
    });
  
     
    return () => {
      eventsToBind.forEach(eventPair => {
        eventPair[0].removeEventListener(eventPair[1], observe);
      });
    };

    }, [stickyRef, sticky]);

    return [stickyRef, sticky];
  }
     

codeIcon imgReact form component

A simple login form component

                
                     import React, { useState } from "react";
                    
                     const defaultFormData = {
                       username: "",
                       password: ""
                     };
                     
                       
                 // Form component
                 const Form = () => {
                  const [user, setUser] = useState(defaultFormData);
                
                  const { username, password } = user;

                   
                  const handleChange = (e) => {
                    setUser((prevState) => ({
                      ...prevState,
                      [e.target.id]: e.target.value
                    }));
                  };
                
                  const handleSubmit = (e) => {
                    e.preventDefault();
                    console.log(user);
                    setUser(defaultFormData);
                  };

                 
                      return (
                        <form onSubmit={handleSubmit}>
                          <h3>Signin</h3>
                    
                          <label htmlFor="username">Username</label>
                    
                          <input
                            onChange={(e) => handleChange(e)}
                            type="text"
                            id="username"
                            value={username}
                            placeholder="enter username"
                          />
                    
                          <label htmlFor="password">Password</label>
                    
                          <input
                            onChange={(e) => handleChange(e)}
                            type="password"
                            id="password"
                            value={password}
                            placeholder="enter password"
                          />
                    
                          <button type="submit">Submit</button>
                        </form>
                      );
                    }