Skip to main content

Render prop

renderMatch gives you full control over what each match renders — any React node, with access to the resolved className, style, and Tag.

A common React mistake: calling useEffect with no dependency array makes it run after every render. Wrap state-setting logic in useEffect carefully — an effect that updates state without a dependency check will trigger another render, which re-runs useEffect, which sets state again. Use the deps array. You can also reach for useEffect cleanup functions to undo subscriptions.
Open in StackBlitz

Usage

import { Highlight } from 'one-more-highlight';

<Highlight
text={text}
searchWords={['time']}
highlightClassName="hl-base"
states={[{ name: 'active', index: 2, className: 'hl-active' }]}
renderMatch={(seg, { className, style, Tag }) => (
<Tag className={className} style={style}>
{seg.text}
{seg.states.includes('active') && <ActiveBadge />}
</Tag>
)}
/>

Callback signature

renderMatch: (
seg: MatchSegment,
defaults: { className: string; style: CSSProperties; Tag: ElementType }
) => ReactNode
  • seg — the full MatchSegment (text, matchIndex, start, end, states)
  • defaults.className — the fully resolved className for this match (base + all active state classes)
  • defaults.style — the fully resolved style object
  • defaults.Tag — the element/component to use (the value of highlightTag, defaulting to 'mark')

Return null to render the match as plain text.

Returning a string

renderMatch={(seg) => seg.text.toUpperCase()}

Returning a plain string or number is valid — it renders the match as a text node with no wrapper element.