Skip to content

Instantly share code, notes, and snippets.

View gragland's full-sized avatar

Gabe Ragland gragland

View GitHub Profile
@gragland
gragland / App.jsx
Last active November 17, 2023 17:05
Next.js routing to dynamic path without hitting server
'use client'
// ⛔️ DISCLAIMER: This is most likely premature optimization and adds code complexity.
// Only use if you really need to shave off that extra 100-200ms.
function MyComponent({ data }){
return (
<a
href={`/item/${data.id}`}
onClick={(e) => {

A fix for Next.js modals (intercepted routes) not closing when navigating away with <Link> or router.push()

app
├─ @photoModal
│  ├─ (.)photo
|  |  └─ [id]
│  │  |  └─ page.tsx <----- a modal with links to home, /profile, and /login
│  └─ [...catchAll]
│ │ └─ page.tsx &lt;----- returning null here is supposed to cause modal to hide when
@gragland
gragland / use-optimistic-mutation-example.ts
Last active November 13, 2023 10:38
useOptimisticMutation for React Query. Optimistically update data in multiple locations with rollback on error.
import axios from 'axios'
import { useOptimisticMutation } from "./useOptimisticMutation.ts"
type Response = boolean
type Error = unknown
type MutationVariables = {itemId: string}
type Items = {id: string; name: string}[]
type Likes = {itemId: string}[]
type History = {type: string}[]
@gragland
gragland / App.js
Last active March 5, 2024 20:05
How to lazy load Firebase with dynamic imports
import getFirebase from "./firebase.js";
function MyApp() {
// Example function that wraps some firebase logic
const onSignup = async (email, password) => {
// Use await to ensure firebase library is loaded
const firebase = await getFirebase();
// Call firebase methods as you normally would
const { user } = await firebase.auth()
.createUserWithEmailAndPassword(email, password);
import React, { useState, useEffect } from 'react';
// Usage
function App(){
// Call hook with function to fire off
// after konami code is entered.
useKonamiCode(() => {
alert('Good job 🥳');
});
@gragland
gragland / use-toggle.jsx
Last active October 5, 2022 05:58
Thought process when creating a useToggle() React hook with useState
import { useState, useCallback } from "react";
function useToggle(initialValue = false){
// State with initial boolean value (true/false)
const [state, setState] = useState(initialValue);
// Let's create a toggle function
// This works, but we're using the state value from above
// instead of the current state. Usually they are the same,
// but if this hook was triggered multiple times rapidly then
@gragland
gragland / use-toggle.jsx
Last active January 10, 2021 00:11
React Hook recipe from https://usehooks.com
import React, { useReducer } from "react";
// Usage
function App(){
const [isOn, toggleIsOn] = useToggle();
return (
<button onClick={toggleIsOn}>
Turn {isOn ? 'Off' : 'On'}
</button>
@gragland
gragland / stripe-webhook.js
Last active January 18, 2024 22:20
Next.js Stripe Webhook from divjoy.com
const getRawBody = require("raw-body");
const { updateUserByCustomerId } = require("./_db.js");
const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY, {
apiVersion: process.env.STRIPE_API_VERSION,
});
// Disable next.js body parsing (stripe needs the raw body to validate the event)
export const config = {
api: {
@gragland
gragland / use-async-improved.jsx
Last active August 28, 2020 23:53
Example for /u/caughtupstream299792
import React, { useState, useEffect, useCallback } from 'react';
// Hook
const useAsync = (asyncFunction, immediate = true) => {
const [status, setStatus] = useState('idle');
const [value, setValue] = useState(null);
const [error, setError] = useState(null);
// The execute function wraps asyncFunction and
// handles setting state for pending, value, and error.
// Usage
function ProfilePage({ uid }) {
// Subscribe to Firestore document
const { data, status, error } = useFirestoreQuery(
firestore.collection("profiles").doc(uid)
);
if (status === "loading"){
return "Loading...";
}