'Is there a way to manipulate rendered text in react component children?

I am trying to write a component that highlights text inside it's children recursively.

What I have been able to achieve, is to highlight the text only if it's explicitly provided in the body component, but I can't find a way to change the text of the component's render part.

Let's say I have the following HighlightText component:
(Note, that this is a concept component. The real component is much more complicated)

const HighlightText = ({highlight, children}) => {
    const regex = new RegExp(`(${regexEscape(highlight)})`, 'gi');
    return React.Children.map(children, child => {
        // Found a text, can highlight
        if (typeof child === 'string') {
            const text = child.trim();
            if (text) {
                return text.split(regex).filter(p => p).map((p, i) =>
                    regex.test(p) ? <mark key={i}>{p}</mark> : <span>{p}</span>;
                );
            }
        }
        
        // If child is a react component, recurse through its children to find more text to highlight
        if (React.isValidElement(child)) {
            if (child.props && child.props.children) {
                return HighlightText({children: child.props.children, highlight});
            }
        }

        // Here I believe, should be another handling that handles the result of the render function to search for more text to highlight...  

        // For any other cases, leave the child as is.
        return child;
    })
}

And some component that renders something:

const SomeContent = () => <div>content</div>;

Now, I want to use the HighlightText component the following way:

ReactDOM.render(

    <HighlightText highlight="e">
        <SomeContent />
        <p>some paragraph</p>
        nude text
    </HighlightText>

,document.body);

The resulted DOM of the the above code is:

<div>content</div>
<p><span>som</span><mark>e</mark><span> paragraph</span></p>
<span>nud</span><mark>e</mark><span> t</span><mark>e</mark><span>xt</span>

But I expect it to be:

<div><span>cont</span><mark>e</mark><span>nt</span></div>
<p><span>som</span><mark>e</mark><span> paragraph</span></p>
<span>nud</span><mark>e</mark><span> t</span><mark>e</mark><span>xt</span>

Any suggestions on how to handle the rendered part of the child component?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source