Skip to content

Instantly share code, notes, and snippets.

View mjackson's full-sized avatar

Michael Jackson mjackson

View GitHub Profile
mjackson /
Last active June 21, 2024 01:54
Notes on route composition in React Router v6, along with a suggested improvement you can make today to start upgrading

Composing <Route> in React Router v6

Composition of <Route> elements in React Router is changing in v6 from how it worked in v4/5 and in Reach Router. React Router v6 is the successor of both React Router v5 and Reach Router.

This document explains our rationale for making the change as well as a pattern you will want to avoid in v6 and a note on how you can start preparing your v5 app for v6 today.


In React Router v5, we had an example of how you could create a element]( to restrict access to certain routes on the page. This element was a simple [wrapper around an actual element that made a simple decision: is the user authenticated or not? If so, ren

mjackson / color-conversion-algorithms.js
Last active June 8, 2024 01:27
RGB, HSV, and HSL color conversion algorithms in JavaScript
* Converts an RGB color value to HSL. Conversion formula
* adapted from
* Assumes r, g, and b are contained in the set [0, 255] and
* returns h, s, and l in the set [0, 1].
* @param Number r The red color value
* @param Number g The green color value
* @param Number b The blue color value
* @return Array The HSL representation
mjackson /
Last active February 18, 2024 21:15
Quickly show/hide desktop icons on macos
# To install: just copy this script to your machine and name it whatever you want.
# Let's say you named it, then all you need to do is make
# the script executable, like this:
# chmod +x
# Now you can execute the script directly in the terminal any time you want to
# show/hide the desktop icons, like this:
import { useState, useEffect, useCallback } from 'react'
function usePromise(createPromise) {
const [error, setError] = useState()
const [value, setValue] = useState()
useEffect(() => {
let current = true
mjackson /
Created February 6, 2018 00:58
Run multiple scripts for the same git hook
# This script should be saved in a git repo as a hook file, e.g. .git/hooks/pre-receive.
# It looks for scripts in the .git/hooks/pre-receive.d directory and executes them in order,
# passing along stdin. If any script exits with a non-zero status, this script exits.
script_dir=$(dirname $0)
hook_name=$(basename $0)
mjackson /
Last active November 12, 2023 07:32
Notes on handling redirects in React Router v6, including a detailed explanation of how this improves on what we used to do in v4/5

Redirects in React Router v6

An important part of "routing" is handling redirects. Redirects usually happen when you want to preserve an old link and send all the traffic bound for that destination to some new URL so you don't end up with broken links.

The way we recommend handling redirects has changed in React Router v6. This document explains why.


In React Router v4/5 (they have the same API, you can read about why we had to bump the major version here) we had a <Redirect> component that you could use to tell the router when to automatically redirect to another URL. You might have used it like this:

mjackson / app.js
Created December 29, 2015 05:07
Using webpack with pixi.js
var PIXI = require('pixi.js')
mjackson / redux-w-keyspace-notifications.js
Last active March 17, 2023 16:53
Redux, with keyspace notifications ala Redis
// I was trying to optimize some redux queries the other day when
// the thought occurred to me that it would be nice if redux let
// you know *what keys* changed instead of just letting you know that
// there was *some* kind of change.
// I was reminded of Redis' "keyspace notifications" (
// that can be used to get notifications about changes in the Redis
// keyspace, and I thought maybe we could try a similar idea in redux.
// So I wrote this little homegrown version of redux, with support for
import React from 'react';
let DataContext = React.createContext();
// A higher-order component for pairing preload function + component ...
function withData(preloadData, Component, autoPreloadOnRender = true) {
let needsPreload = !!autoPreloadOnRender;
let promise;
let value;
mjackson / download-counts.mjs
Last active November 11, 2022 05:43
Download counts for react-router
const npmApiUrl = "";
async function fetchDownloadCounts(packageName, year) {
let range = `${year}-01-01:${year}-12-31`;
let response = await fetch(`${npmApiUrl}/${range}/${packageName}`);
return (await response.json()).downloads;
async function getDownloads(startYear, endYear = startYear) {
if (endYear < startYear) {