mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
* chore(ai-workflow): track repo-managed review tooling * fix(ai-workflow): remove repo-specific path assumptions Make shared workflow hooks and APK testing guidance resolve paths from the repo and contributor environment so the tooling works for all contributors, not just one machine.
46 lines
1.0 KiB
Markdown
46 lines
1.0 KiB
Markdown
---
|
|
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) => ...)}</>
|
|
}
|
|
```
|
|
|
|
**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) => ...)}</>
|
|
}
|
|
```
|
|
|
|
**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
|
|
```
|