Avoid high mem ops in render functions
 
In React functional components, the body of your function is processed on EVERY render cycle. It is important to consider this and try to reduce processing power and memory usage whenever possible.
 
Consider these examples:
 
// ❌ emojis does not use props or state, it does not need to live inside the render
// function. This creates an array ON EVERY RENDER
const MyStaticComponent = () => {
const emojis = Array.from({length: 5}, () => <div className="w-2 h-2">😭</div>)
 
return (
 
<>{emojis}</>) }
 
// βœ… emojis is created once and then reused. This is the most ideal form as
// the calculation is done once ever, outside of the render loop (non-blocking)
const emojis = Array.from({length: 5}, () => <div className="w-2 h-2">😭</div>)
const MyStaticComponent = () => (
 
{' '}
 
<>{emojis}</>)
 
// ❌ This array gets freshly created on every render. This might be not be a problem
// if the component is rendered once on a page, but consider a situation where you
// render a 100 list of user reviews, each with their own rating. Now every page render
// has to recreate 100 arrays!
const MyRatings = ({ ratings }: { ratings: number[] }) => (
 
{' '}
 
<div className="some-css">
  {ratings.map((todo) => (
    <div key={`${rating}`}>{rating}</div>
  ))}
</div>
)
 
// βœ… Now each ratings component is only rendered once as long as the ratings
// do no change. Now the calculations are only done on the first page render.
const MyRatings = ({ ratings }: { ratings: number[] }) => {
const ratingsComponent = useMemo(
() => ratings.map(
todo => <div key={`${rating}`}>{ rating }</div>
)
, [ratings])
return (
 
<div className="some-css">{ratingsComponent}</div>) }
 
// ❌ This button component creates a new onClick event function on EVERY RENDER
// #DeathByOneThousandCuts
const MyButton = ({ parentOnClick }: { parentOnClick: (e: MouseEvent) => void }) => (
 
  <button onClick={(e) => {
       // do something
 
       // handle parent event
       parentOnClick(e)
      }
    }>
    My button
 
  </div>
)
 
// βœ… Now the handler is only created once (unless the props change).
// This Component can now be rendered hundreds/thousands of times on a page and still be performant
const MyButton = ({ parentOnClick }: { parentOnClick: (e: MouseEvent) => void }) => {
const buttonHandler = useCallback((e: MouseEvent) => {
// do something
 
    // handle parent event
    parentOnClick(e)
 
},[parentOnClick])
 
return (
 
<button onClick={buttonHandler}>
My button
</div>
)
}
 
Prefer children over components as props
 
Use children only if it's a 1:1 child being rendered (add Container example)
 
Add official
 
Use named props
 
Prefer children over components as props
 
If a child is just being directly rendered in the β€œbody” of your component. Use children.
 
// ❌ Needlessly verbose and can have weird edge cases
const WrapWithEmoji = ({ ComponentToWrap, emoji }: { ComponentToWrap: JSX.Element, emoji: string }) => (
 
{' '}
 
<>
  {emoji}
  {ComponentToWrap}
  {emoji}
</>
)
 
// βœ… Uses native react types. Handles children in native react way.
const WrapWithEmoji = ({ children, emoji }: PropsWithChildren<{ emoji: string }>) => (
 
{' '}
 
<>
  {emoji}
  {children}
  {emoji}
</>
)
 
The exception to this rule
 
When you require component props to be used in unconventional layouts where the child isn’t obviously the β€œbody” of the component. Or when you have multiple components being used at once in specific ways.
 
// ❌ children is being used in a non-universal way. Very error prone. Not obvious
// from the parent where the children are going
const MyLayout = ({ children, emoji }: PropsWithChildren<{ emoji: string }>) => (
 
{' '}
 
<header>{children[0]}</header>
My Cool Layout! {emoji}
<div>{children[1]}</div>
<footer>{children[2]}</footer>)
 
// βœ… Props clearly define what the conponent is using the child for. Doesnt have
// all the ReactChildren edge cases
type MyLayoutProps = {
Header: JSX.Element,
Body: JSX.Element,
Footer: JSX.Element,
emoji: string
}
const MyLayout = ({ Header, Body, Footer, emoji }: MyLayoutProps) => (
 
{' '}
 
<header>{Header}</header>
My Cool Layout! {emoji}
<div>{Body}</div>
<footer>{Footer}</footer>)
 
Don’t use array index as key
 
Rendered arrays in React use keys in order to save time on render. When a prop array that is rendered changes, React uses the key to figure out where to add/remove rows so that it doesn’t have to rerender the entire array. If you use the index as the key, the entire array needs to rerender whenever there is a change. See official docs for more info.
 
// ❌ List completely rerenders on every change to listItems
const MyList = ({ listItems } : { listItems: string[]) => (
 
{' '}
 
<>
  listItems.map((item, index) => <div key={index}>{item}</div>)
</>
)
 
// βœ… Assuming listItem strings are unique this works.
const MyList = ({ listItems } : { listItems: string[]) => (
 
{' '}
 
<>
  listItems.map((item) => <div key={item}>{item}</div>)
</>
)
 
// Or defer ordering to parent
 
// βœ… Let the parent decide what unique key to use
type ListItem = {
item: string
key: string
}
const MyList = ({ listItems } : { listItems: ListItem[]) => (
 
{' '}
 
<>
  listItems.map(({(item, key)}) => <div key={key}>{item}</div>)
</>
)
 
Avoid complex/nested ternaries in render loop
 
Complex conditionals or nested ternary statements make it hard for people to reason about what is rendering. Instead, use the early return pattern (AKA guard statements). In cases where early returns do not work. Consider encapsulated ternaries in useMemoand then treating them like components.
 
// ❌ Logic is hard to follow. Lots of things are kinda repeated
const MyPage = () => {
const { loading, data, error} = useSomeQuery()
const { loading: loading2, data: data2, error: error2} = useSomeOtherQuery()
 
return (
 
<>
{ loading && !error2 ? <Loading/> : loading2 ? <Loading/> : <MyHappyPathComponent data={{...data, ...data2}}/> : null }
{ error || error2 ? error ? <DisplayError error={error}/> : <DisplayError error={error2}/> : null}
</>
)
}
 
// βœ… Way easier to read.
const MyPage = () => {
const { loading, data, error} = useSomeQuery()
 
if(error) return <DisplayError error={error}/>
if(loading) return <Loading/>
 
// Please dont actually rename variables like this.Doing it for the demo...
const { loading: loading2, data: data2, error: error2} = useSomeOtherQuery()
 
if(error2) return <DisplayError error={error2}/>
if(loading2) return <Loading/>
 
return (<MyHappyPathComponent data={{...data, ...data2}}/>)
}
 
// βœ… Another way to do it when logic is coupled between lots of states.
// Ideally you want to extract SomeQueryComponent and SomeOtherQueryComponent
// into their own component function if possible. If you can't, this is a
// clean and performant way of rendering it.
const MyPage = () => {
const { loading, data, error} = useSomeQuery()
 
const SomeQueryComponent = useMemo(() => {
if(error) return <DisplayError error={error}/>
if(loading) return <Loading/>
return <SomeComponent data={data}/>
}, [error,loading, data])
 
const SomeOtherQueryComponent = useMemo(() => {
if(error2) return <DisplayError error={error}/>
if(loading2) return <Loading/>
return <SomeComponent data={data2}/>
}, [error2,loading2, data2])
 
return (
 
<article>
<p>Some text</p>
 
      <h2>Something dependant on data</h2>
      {SomeQueryComponent}
 
      <h2>Something dependant on data2</h2>
      {SomeOtherQueryComponent}
    </article>
 
)
}
 
Keep HTML as flat as possible
 
As a general rule, the less HTML on the page, the faster it is to render and the easier it is to debug. React provides fragments in order to facilitate grouping HTML without needing to use an HTML element.
 
// ❌ The div likely does nothing here. It carries no styling, and makes using this
// component in the parent harder to style
const MyList = ({ listItems } : { listItems: string[]) => (
 
  <div>
    listItems.map((item) => <div key={item}>{item}</div>)
  <div/>
)
 
// βœ… the "`<>`" dissapears on render leaving you with clean HTML
const MyList = ({ listItems } : { listItems: string[]) => (
 
{' '}
 
<>
  listItems.map((item) => <div key={item}>{item}</div>)
</>
)
 
Use ternaries instead of &&
 
Usually when something is missing we want to render null or undefined. But by not expliciting returning null using a ternary, we could have to deal with some unexpected behaviour because, for example, in JS 0 && "hey" returns 0
 
// ❌ This will render: <ul>0</ul>
function ContactList() {
const contacts = []
return (
 
<ul>
{contacts.length &&
contacts.map((contact) => (
<li key={contact.id}>
{contact.name}
</li>
))}
</ul>
)
}
// βœ… This will render <ul></ul>
function ContactList() {
const contacts = []
return (
<ul>
{contacts.length ?
contacts.map((contact) => (
<li key={contact.id}>
{contact.name}
</li>
): null}
</ul>
)
}
 
This also happens with "" which is a very common scenario.
 
See https://kentcdodds.com/blog/use-ternaries-rather-than-and-and-in-jsx for a more in-depth explanation
 
/**
 * TypeScript Utilities
 */
export type ValidValue<T> = Exclude<T, null | undefined | 0 | '' | false>
export type Optional<T> = T | undefined | null
 
/**
 * Just like .filter(Boolean), but allows TypeScript to exclude falsy values in return type
 * @example
 * ```ts
 * const x = [1, 2, 3, "", null, undefined, 0, false]
 * const y = x.filter(BooleanFilter)
 * // y is [1, 2, 3]
 * ```
 */
export const BooleanFilter = <T,>(x: T): x is ValidValue<T> => Boolean(x)
export type UnwrapPromise<T> = T extends Promise<infer U> ? U : T
 
/**
 * Strings
 */
export function capitaliseFirstChar(str: string) {
  return str.charAt(0).toUpperCase() + str.slice(1)
}
 
export function enumToNiceString(str: string) {
  const newStr = str
    .replace(/_/g, ' ')
    .replace(/([A-Z])/g, ' $1')
    .trim()
    .toLowerCase()
  return str.charAt(0).toUpperCase() + str.slice(1)
}
 
/**
 * Money
 */
export const formatMoneyCompact = (
  currency: string | undefined,
  amount: number,
) =>
  new Intl.NumberFormat('en-GB', {
    ...(currency && {
      style: 'currency',
      currency: currency,
    }),
    notation: 'compact',
    minimumFractionDigits: 0,
  }).format(amount)
 
export const formatMoney = (currency: string | undefined, amount: number) => {
  return new Intl.NumberFormat('en-GB', {
    ...(currency && {
      style: 'currency',
      currency: currency,
    }),
    minimumFractionDigits: 2,
    currencyDisplay: 'narrowSymbol',
  }).format(amount)
}
/**
 * Cookies
 */
 
export const saveCookie = ({
  key,
  value,
  maxAgeInSeconds = 30 * 24 * 60 * 60, // 30 days,
}: {
  key: string
  value: string | null
  maxAgeInSeconds?: number
}): void => {
  if (value === null) {
    return
  }
  const domain = window?.location?.hostname?.split('.').slice(-2).join('.') // e.g. "blinkist.com"
 
  document.cookie = `${key}=${value}; path=/; domain=.${domain}; max-age=${maxAgeInSeconds};`
}
 
export const getAllCookies = (): Record<string, string> | null => {
  if (typeof window === 'undefined') {
    return null
  }
 
  return document.cookie.split(';').reduce(
    (acc, curr) =>
      Object.assign(acc, {
        [curr?.split('=')?.[0]?.trim() ?? '']: curr?.split('=')?.[1] ?? '',
      }),
    {},
  )
}
 
export const getCookie = (key: string): string | null => {
  return getAllCookies()?.[key] ?? null
}
 
/**
 * Utils
 */
type Entries<T> = {
  [K in keyof T]: [K, T[K]]
}[keyof T][]
 
export const getEntries = <T extends object>(obj: T) =>
  Object.entries(obj) as Entries<T>
  {
    "key": "cmd+down",
    "command": "cursorMove",
    "when": "editorTextFocus",
    "args": {
      "to": "nextBlankLine",
      "by": "wrappedLine"
    }
  },
  {
    "key": "cmd+up",
    "command": "cursorMove",
    "when": "editorTextFocus",
    "args": {
      "to": "prevBlankLine",
      "by": "wrappedLine"
    }
  }
const t = Array(5)
// [ <5 empty items> ]
t.forEach((\_,i) => console.log(i))
// ❌ nothing is printed
 
const t = Array.from({length: 5})
// [ undefined, undefined, undefined, undefined, undefined ]
t.forEach((\_,i) => console.log(i))
// βœ… 0...4 is printed
 
// βœ… With initialization
const t = Array.from({length: 5}, (\_,i). => i+1)
// [1,2,3,4,5]

Design Component Libraries

SEO

Typescript Goodies

type PropsWithChildren<P = unknown> = P & { children?: React.ReactNode }

PropsWithChildren

Landing page inspirations

My favorite blog posts

Startup

Typescript Goodies

  • React type: PropsWithChildren

Tips

Python

AI tools

React type: PropsWithChildren

type PropsWithChildren<P> = P & { children?: ReactNode }

The best way to type icons

export const CheckedIcon = (props: SVGProps<SVGSVGElement>) => {
  return (
    <svg
      viewBox="0 0 24 24"
      fill="none"
      xmlns="http://www.w3.org/2000/svg"
      {...props}
    >
      <path
        d="M10.7388 16.0732L7.00793 12.3423L7.97487 11.3731L10.7388 14.1371L16.5336 8.3446L17.5005 9.31154L10.7388 16.0732Z"
        fill="currentColor"
      />
    </svg>
  )
}