--- title: Hoist RegExp Creation impact: LOW-MEDIUM impactDescription: avoids recreation tags: javascript, regexp, optimization, memoization --- ## Hoist RegExp Creation Don't create RegExp inside render. Hoist to module scope or memoize with `useMemo()`. **Incorrect (new RegExp every render):** ```tsx function Highlighter({ text, query }: Props) { const regex = new RegExp(`(${query})`, "gi"); const parts = text.split(regex); return <>{parts.map((part, i) => part)}; } ``` **Correct (memoize or hoist):** ```tsx 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) => part)}; } ``` **Warning (global regex has mutable state):** Global regex (`/g`) has mutable `lastIndex` state: ```typescript const regex = /foo/g; regex.test("foo"); // true, lastIndex = 3 regex.test("foo"); // false, lastIndex = 0 ```