Lets say I have an array of objects:
const options = [
{
text: "this is the text",
description: "The word 'test' should be bold"
},
{
text: "this is the text",
description: "The word 'another-word' should be bold"
}
]
the component renders something like this:
return (
{
options.map(option => {
<p className="text-green-500">{option.description}</p>
})
}
)
Now I have to make the word/s "test" and "another-word" bold respectively. In some cases it has to only be characters inside a word.
CodePudding user response:
You could create a function which replaces the string in ''
with a <b>
wrappers.
const highlight = (text) => text.replace(/'([^'] )'/g, "<b>$1</b>")
Then set the innerHTML like this:
return options.map(({ description }) =>
<p dangerouslySetInnerHTML={{ __html: highlight(description) }}></p>
)
You need to sanitize the string before doing this if these string are user inputs.
const highlight = (text) => text.replace(/'([^'] )'/g, "<b>$1</b>")
function App() {
const options = [{
text: "this is the text",
description: "The word 'test' should be bold"
},
{
text: "this is the text",
description: "The word 'another-word' should be bold"
}
]
return options.map(({ description }) =>
<p dangerouslySetInnerHTML={{ __html: highlight(description) }}></p>
)
};
ReactDOM.render(<App />, document.getElementById("root"));
<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>
<div id="root"></div>
You can avoid the innerHTML route entirely. In that case, you need split each string into fragments and then render them.
const highlight = (text) =>
Array.from(text.matchAll(/([^']*)'*([^']*)'*([^']*)/g), ([m, p1, p2, p3]) =>
m ? (
<>
{p1}
<b>{p2}</b>
{p3}
</>
) : null
);
And render it like this:
return options.map(({ description }) =>
<p>{highlight(description)}</p>
)
CodePudding user response:
This is probably the easiest way to do it, just return a chunk of JSX from a function that deals with bolding the part of the text.
Stackblitz to run the code: https://stackblitz.com/edit/react-ts-gewz6v?file=App.tsx,index.tsx
const options = [
{
text: 'this is the text',
description: "The word 'test' should be bold",
},
{
text: 'this is the text',
description: "The word 'another-word' should be bold",
},
];
const boldText = (text) => {
const termToBold = text.match(/'([^'] )'/)[1];
const startIndex = text.toLowerCase().indexOf("'");
return (
<React.Fragment>
{text.slice(0, startIndex)}
<strong>
{text.slice(startIndex, startIndex 2 termToBold.length)}
</strong>
{text.slice(startIndex 2 termToBold.length)}
</React.Fragment>
);
};
return (
<div>
{' '}
{options.map((option) => {
return <p className="text-green-500">{boldText(option.description)}</p>;
})}
</div>
);