Based on a function I've seen here I am trying to build a component that highlights every word from an array I'll provide, inside the string I give it.
For example, if I'll use it like this:
<Highlight
body="Hi there stack overflow, hope you're all well"
items={["there", "hope"]}
/>
What I'd like to get back is:
Hi there stack overflow, hope you're all well
So sometimes it works, and other times it doesn't, and I can't figure out the pattern.
Using the example string, if I'll give it this array ["there"]
then I'll get it correctly printing:
Hi there stack overflow, hope you're all well
If I'll give it this array ["there", "hope"]
then I'll get it correctly printing:
Hi there stack overflow, hope you're all well
BUT if I'll give it this array ["there", "hope", "overflow"]
then I'll get this weird string:
Hi there stack overflow, hopeoverflowoverflowoverflow, hope you're all well
This is my function currently:
const highlightWords = (source, target, callback) => {
if (!source) return res;
if (!target) return source;
const defaultHighlight = s => <em key={Math.random(1000)}>{s}</em>;
const res = [source];
let lastOffset = 0;
target.forEach(element => {
res.forEach(stringEl => {
console.log(typeof stringEl)
if (typeof stringEl === typeof "")
// Uses replace callback, but not its return value
stringEl.replace(new RegExp(element, "gi"), (val, offset) => {
// Push both the last part of the string, and the new part with the highlight
res.push(
stringEl.substr(lastOffset, offset - lastOffset),
// Replace the string with JSX or anything.
(callback || defaultHighlight)(val)
);
lastOffset = offset + val.length;
});
});
});
// Push the last non-highlighted string
res.push(source.substr(lastOffset));
res.shift();
return res;
};
And this is my component:
export const Highlight = ({ body, items}) => {
return (
<div>
{highlightWords(body, items, s => (
<span className="bold-700" key={Math.random(1000)}>
{s}
</span>
))}
</div>
);
};