[英]React JSX - make substring in bold
While creating custom autocomplete component I stuck with this problem: I got a string and substring(first part of the string, the one that user enters in autocompete field), and I need to show that part in bold in results list.在创建自定义自动完成组件时,我遇到了这个问题:我得到了一个字符串和子字符串(字符串的第一部分,用户在自动竞争字段中输入的部分),我需要在结果列表中以粗体显示该部分。
But I cannot use str.replace
like但我不能像这样使用str.replace
var re = new RegExp(find, 'g');
return str.replace(re, '<b>'+find+'</b>');
because it will return string and I need JSX.因为它将返回字符串并且我需要 JSX。
So basically the problem is - I have JSX and I need to make some part of it in bold.所以基本上问题是 - 我有 JSX,我需要用粗体显示它的某些部分。 I need a function that takes JSX and like inject <b>
tag in it in special places我需要一个 function,它采用 JSX 并且喜欢在特殊位置注入<b>
标签
This is what I got so far这是我到目前为止得到的
boldJSX(str, find){
if(!find) return str;
return <span><b>{find}</b>{str.slice(find.length)}</span>
}
I seem to have found a more 'reactish' approach for those who come here in the future对于未来来这里的人,我似乎找到了一种更“反动”的方法
function BoldedText({ text, shouldBeBold }) {
const textArray = text.split(shouldBeBold);
return (
<span>
{textArray.map((item, index) => (
<>
{item}
{index !== textArray.length - 1 && (
<b>{shouldBeBold}</b>
)}
</>
))}
</span>
);
}
First, you need to find and extract the appropriate substring (the string you are looking for) if exits in given list and make a custom string by extracting that substring as given below.首先,如果在给定列表中存在,您需要查找并提取适当的子字符串(您正在查找的字符串),并通过提取该子字符串来创建自定义字符串,如下所示。
//autoValue - value you are looking for
//main - item value
const val =
main.slice(0, main.indexOf(autoValue)) +
"<b>" +
autoValue +
"</b>" +
main.slice(
main.indexOf(autoValue) + autoValue.length,
main.length
);
Now, You have to use dangerouslySetInnerHTML
for a span
or any custom HTML
component you are using for rendering each item in you auto-complete component.现在,您必须将dangerouslySetInnerHTML
用于span
或用于呈现自动完成组件中的每个项目的任何自定义HTML
组件。 Here is full example.这是完整的例子。
const items = [
"React",
"Angular",
"Vue",
"Node",
"Express",
"PHP",
"Laravel",
"Material",
"CSS",
"HTML"
];
function ListItem(props) {
if (props.value.indexOf(props.autoValue) > -1 && props.autoValue.length > 0) {
const main = props.value;
const val =
main.slice(0, main.indexOf(props.autoValue)) +
"<b>" +
props.autoValue +
"</b>" +
main.slice(
main.indexOf(props.autoValue) + props.autoValue.length,
main.length
);
return (
<div>
<span dangerouslySetInnerHTML={{ __html: val }} />
<hr />
</div>
);
} else {
return (
<span>
{props.value}
<hr />
</span>
);
}
}
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map(number => (
<ListItem
key={number.toString()}
value={number}
autoValue={props.autoValue}
/>
));
return <div>{listItems}</div>;
}
class App extends Component {
constructor(props) {
super(props);
this.state = {
inputValue: ""
};
this.update = this.update.bind(this);
}
update(e) {
e.preventDefault();
this.setState({ inputValue: e.target.value });
}
render() {
return (
<div>
<input
type="text"
onChange={this.update}
name="inputValue"
value={this.state.inputValue}
/>
<NumberList numbers={items} autoValue={this.state.inputValue} />
<span> {this.state.inputValue} </span>
</div>
);
}
}
export default App;
Working Example.工作示例。 https://codesandbox.io/s/n9n65wqj5j https://codesandbox.io/s/n9n65wqj5j
Expanding upon @mantas-giniūnas solution, I've enhanced it to maintain letter-casing.扩展 @mantas-giniūnas 解决方案,我对其进行了增强以保持字母大小写。
function BoldedText({ text, shouldBeBold }) {
const textArray = text.split(RegExp(shouldBeBold, "ig"));
const match = text.match(RegExp(shouldBeBold, "ig"));
return (
<span>
{textArray.map((item, index) => (
<>
{item}
{index !== textArray.length - 1 && match && (
<b>{match[index]}</b>
)}
</>
))}
</span>
);
}
Assuming you already know that the suggestion passed in matches the filter you can do假设您已经知道传入的建议与您可以执行的过滤器匹配
getSuggestionText = (suggestion, filter) => (
<span>
<b>{suggestion.slice(0, filter.length}</b>
{suggestion.slice(filter.length)}
</span>
);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.