Skip to content

Instantly share code, notes, and snippets.

@darcher-
Last active March 10, 2023 16:26
Show Gist options
  • Save darcher-/9a86f8f069c102468911f38e03f623c3 to your computer and use it in GitHub Desktop.
Save darcher-/9a86f8f069c102468911f38e03f623c3 to your computer and use it in GitHub Desktop.
Structured lazy dynamic imports - serve only what is required.
import { lazy } from "react";
/**
* use dynamic "code-splitting" imports
* prevents all components from being bundled and loaded at runtime
* only serves what is being utilized at render
*/
class DynamicComponent {
private _node = {
tricky: lazy(() => import("./dynamic-prop-state-management")),
simple: lazy(() => import("./runtime-prop-state-management")),
loader: lazy(() => import("./icon-loader")),
};
getElement() {
return {
Tricky: this._node.tricky,
Loader: this._node.loader,
Simple: this._node.simple,
};
}
}
const Component = new DynamicComponent().getElement();
//? export individually
export const Tricky = Component.Tricky;
export const Loader = Component.Loader;
export const Simple = Component.Simple;
//? pass all methods to default export
export default { ...Component } as const;
/**
* only call what is needed
* avoid using:
* - import React from 'react'
* - import * as React from 'react'
*/
import {
Fragment,
Suspense,
memo,
useId,
useRef,
useEffect,
useReducer,
} from "react";
//? call only what is used
import { Loader } from "src/components";
//? memoize components where able
export default memo((props: { running: boolean; time: number; }) => {
//? dynamic props that rely on each other should utilize useReducer call
const [state, dispatch] = useReducer<
{ running: boolean; time: number; },
{ type: "reset" | "start" | "stop" | "tick"; },
//TODO: if reused, hoist to type or abstract to types.d file
{ running: boolean; time: number; }
//TODO: the first argument can be abstracted to utilities if used frequently
>((state, action) => {
switch (action.type) {
case "start": { return { ...state, running: true } };
case "stop": { return { ...state, running: false } };
case "tick": { return { ...state, time: state.time + 1 } };
case "reset": { return { running: false, time: 0 } };
default: { throw new Error("I broked it!") };
}
}, props);
const ref: { current: number } = useRef(0);
useEffect((): void | { (): void } => {
if (state.running) {
ref.current = setInterval(
() => dispatch({ type: "tick" }),
1000
);
return () => {
clearInterval(ref.current);
ref.current = 0;
};
}
}, [state.running]);
return (
{/*? use Suspense fallback to indicate load state*/}
<Suspense fallback={<Loader />}>
{/*? assign unique id to Fragment key */}
<Fragment key={useId()}>
<p className={`timespan`}>
<strong>{state.time}s</strong>
</p>
<div className={`actions`}>
<button onClick={() => dispatch({ type: "start" })}>Start</button>
<button onClick={() => dispatch({ type: "stop" })}>Stop</button>
<button onClick={() => dispatch({ type: "reset" })}>Reset</button>
</div>
</Fragment>
</Suspense>
);
});
/**
* only call what is needed
* avoid using:
* - import React from 'react'
* - import * as React from 'react'
*/
import { Fragment, memo, useId } from "react";
//? memoize components where able
export default memo(() => {
return (
{/*? assign unique id to Fragment key */}
<Fragment key={useId()}>
<svg
className={`icon icon-loader`}
fill={`currentColor`}
{/*? always make svg elements unfocusable */}
focusable={true}
height={64}
{/*? assign as role="img" or aria-hidden="true" depending on need */}
role={`img`}
width={64}
viewBox={`0 0 50 50`}
>
<path
d={`
M25,5A20.14,20.14,0,0,1,45,22.88a2.51,2.51,0,0,0,
2.49,2.26h0A2.52,2.52,0,0,0,50,22.33a25.14,25.14,
0,0,0-50,0,2.52,2.52,0,0,0,2.5,2.81h0A2.51,2.51,
0,0,0,5,22.88,20.14,20.14,0,0,1,25,5Z
`}
>
<animateTransform
attributeName={`transform`}
type={`rotate`}
from={`0 25 25`}
to={`360 25 25`}
dur={`0.5s`}
repeatCount={`indefinite`}
/>
</path>
</svg>
</Fragment>
);
});
import { StrictMode, Suspense } from "react";
import { createRoot } from "react-dom/client";
//? we use all components; so we can namespace it
import Component from "./components";
//TODO: this should be abstracted to fixtures
const CPROPS = { running: false, time: 0 };
const SPROPS = { name: "Spot", age: 13, type: "dog" };
createRoot(document.getElementById("root")! as HTMLElement).render(
{/*? always utilize strict mode */}
<StrictMode>
{/*? use Suspense fallback to indicate load state*/}
<Suspense fallback={<Component.Loader />}>
{/*? when not in Function Component we can use Fragment shorthand */}
<>
<Component.Tricky {...CPROPS} />
<Component.Simple {...SPROPS} />
<Bad />
<>
</Suspense>
</StrictMode>
);
/**
* only call what is needed
* avoid using:
* - import React from 'react'
* - import * as React from 'react'
*/
import {
Fragment,
FunctionComponent,
Suspense,
memo,
useEffect,
useId,
useState,
} from "react";
//? call only what is used
import { Loader } from "src/components";
//? memoize components where able
export default memo((props: {
/**
* Explicitly define props; avoid dynamic typing (for now)
* e.g. this could easily be on of the following:
* - Partial<Record<string, string | number | boolean>>
* - Partial<{ [K: string]: string | number | boolean }>
* - { [K in 'name' | 'age' | 'elder' | 'title' | 'type']?: string | number | boolean }
*/
name: string;
age: number;
elder?: boolean;
title?: string;
type: string;
}) => {
//? feed all props to single useState call
const [state, setState] = useState({
...props,
elder: false,
});
//? runtime updates
useEffect((): void => {
setState((etc) => ({
...etc,
title: {
dog: "canine",
cat: "feline",
}[etc.type],
}));
}, [state.type]);
//? split updates into separate useEffect calls
useEffect((): void => {
setState((etc) => ({
...etc,
elder: etc.age > 7,
}));
}, [state.elder]);
//* you can destructure state here if you'd prefer
return (
{/*? use Suspense fallback to indicate load state*/}
<Suspense fallback={<Loader />}>
{/*? assign unique id to Fragment key */}
<Fragment key={useId()}>
<dl className={`pet`}>
<dt>Pet Name</dt>
<dd>{state.name}</dd>
<dt>Age</dt>
<dd>{state.age}</dd>
<dt>Status</dt>
<dd>{state.title} {state.elder ? `Elder` : `Pup`}</dd>
</dl>
</Fragment>
</Suspense>
);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment