Reputation: 19341
I am trying to highlight some text in React pre. But, it doesn't seems working. It shows [object Object]
instead of text.
const Text = styled.pre `
color: black;
padding-bottom: 10px;
`;
const HighLight = styled.span `
color: red;
`;
let obj = [{
id: 123,
name: 'abcd',
}, {
id: 234,
name: 'new name',
}];
let str = "[123] Hello how are you? [234] and you? [123] Please call me.";
obj.forEach(o => {
str = str.replace(new RegExp('\\[' + o.id + '\\]', 'gi'), <HighLight>{o.name}</HighLight>);
});
console.log(str);
render() {
return ( <Text> {str}</Text>);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
Also I tried following but, same result
const Text = styled.span `
color: black;
padding-bottom: 10px;
`;
<Text dangerouslySetInnerHTML={{ __html: str }} />
Any help would be greatly appreciated.
Upvotes: 0
Views: 217
Reputation: 816810
As I have mentioned in my comment, you cannot insert React elements into a string because React elements are objects. Instead you have to somehow parse the string and create a list of React elements instead.
In your specific example you can get away with using a regular expression to split the string and map every part to either itself (plain string) or a React element, if it matches the pattern. We take advantage of the fact that JavaScript includes the delimiter in the result array if we us
function HighLight({children}) {
return <strong>{children}</strong>;
}
let obj = [{
id: 123,
name: 'abcd',
}, {
id: 234,
name: 'new name',
}];
const elements = "[123] Hello how are you? [234] and you? [123] Please call me.".split(/(\[\d+\])/).map(match => {
if (/\[\d+\]/.test(match)) {
return (
<HighLight>
{obj.find(o => o.id === Number(match.slice(1,-1))).name}
</HighLight>
);
}
return match;
});
ReactDOM.render(
elements,
document.body
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
Of course if you change your data structure to use the IDs as property names, then getting the right object would be easier.
I would have suggested to use a custom tagged template but I assume that you have no control over the string input.
Upvotes: 2