Skip to main content

Js Hoist Regexp

Source: .agents/references/coding-standard/vercel-react-best-practices/rules/js-hoist-regexp.md

Metadata

  • title: Hoist RegExp Creation
  • impact: LOW-MEDIUM
  • impactDescription: avoids recreation
  • tags: javascript, regexp, optimization, memoization

Content

Hoist RegExp Creation

Don't create RegExp inside render. Hoist to module scope or memoize with useMemo().

Incorrect (new RegExp every render):

function Highlighter({ text, query }: Props) {
const regex = new RegExp(`(${query})`, 'gi')
const parts = text.split(regex)
return <>{parts.map((part, i) => ...)}</>
}

Correct (memoize or hoist):

const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/

function Highlighter({ text, query }: Props) {
const regex = useMemo(
() => new RegExp(`(${escapeRegex(query)})`, 'gi'),
[query]
)
const parts = text.split(regex)
return <>{parts.map((part, i) => ...)}</>
}

Warning (global regex has mutable state):

Global regex (/g) has mutable lastIndex state:

const regex = /foo/g
regex.test('foo') // true, lastIndex = 3
regex.test('foo') // false, lastIndex = 0