Snippets
useWindowSize
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; }
React 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]; }
React 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> ); }