例如,如何将 React.js 中的部分搜索词设置为粗体或浅色?
How do I style part of my searched word in React.js, to bold or lighter, for instance?
我发现了一些密切相关的问题,但还不够接近。我正在尝试仅设置搜索结果的搜索部分的样式。例如,如果查询是 "Thi", 我希望结果显示为 Things fall apart。我的问题是它在浏览器内部呈现 [object Object]。如何让它呈现所需的文本,以便我可以使用 CSS3 自由设置样式?我遇到的另一个问题是浏览器控制台中的警告
index.js:1 Warning: Each child in a list should have a unique "key" prop.
代码如下:
import React, { Fragment } from "react";
import CancelIcon from "@material-ui/icons/Cancel";
import CallMadeIcon from "@material-ui/icons/CallMade";
export default function SearchBar(props) {
return (
<Fragment>
<div className="search">
<div
className="search-input-container"
ref={props.searchInputContainerRef}
>
<label htmlFor="search-input"></label>
<input
type="text"
id="search-input"
placeholder={props.placeholder}
onChange={props.handleSetSearchTerm}
value={props.searchTerm}
ref={props.searchInputRef}
onFocus={props.blurAllOnSearch}
onBlur={props.blurAllOnSearch}
onKeyUp={props.handleFilter}
/>
{props.searchTerm === "" ? (
<button
ref={props.searchIconVectorRef}
type="button"
className="search-icon-btn"
onClick={props.focusSearchInput}
></button>
) : (
<CancelIcon
className="clear-btn"
type="button"
onClick={props.clearSearchInput}
/>
)}
<button className="go-search-btn">Go</button>
</div>
{props.searchResults.length !== 0 && (
<div className="search-results">
{props.searchResults.slice(0, 15).map((value, key) => {
const boldResultPart = (result, query) => {
let re = new RegExp(query, "ig");
return result
.replace(/- /g, "")
.replace(/\./g, "")
.replace(re, <span className="boldFont"> ${query} </span>); // <-- *My problem is this span renders as [object Object] in the browser*
};
let bolded = boldResultPart(value.title, props.searchTerm);
return (
<li className="data-item">
<a
className="result"
href={value.link}
target="_blank"
rel="noreferrer"
>
{bolded}
</a>
<CallMadeIcon className="call-made-icon" />
</li>
);
})}
</div>
)}
</div>
</Fragment>
);
}
替换会将您的 Span 转换为字符串。尝试根据正则表达式的结果创建跨度。这是一个例子:
function SearchBar(props) {
return <div>
{props?.searchResults.length && (
<div className="search-results">
{props.searchResults.slice(0, 15).map(value => {
const boldResultPart = (result, query) => {
let re = new RegExp(query, "ig");
let results = result.replace(/- /g, "")
.replace(/\./g, "")
.split(re);
return [results, [...(result.matchAll(re))].map(x => x[0])]
};
const [resultSplit, resultFind] = boldResultPart(value.title, props.searchTerm)
const makeBold = (q) => <strong className="boldFont">{q}</strong>
const bolded = resultSplit.map((i,c) => c ? <span key={c}>{makeBold(resultFind[c-1])}{i}</span> : i);
return (
<li key={value.title} className="data-item">
<a
className="result"
href={value.link}
target="_blank"
rel="noreferrer"
>
{bolded}
</a>
</li>
);
})}
</div>
)}
</div>
}
const Container = () => {
return <SearchBar
searchResults={[
{ title: '', link: '/fooa' },
{ title: 'A', link: '/fooa' },
{ title: 'Afoo', link: '/fooa' },
{ title: 'AfooA', link: '/fooa' },
{ title: 'Foobar', link: '/barbar' },
{ title: 'Foobar foo', link: '/barbar' },
{ title: 'Foobar Foo', link: '/barbar' },
{ title: 'Afoo A Foobar', link: '/barbar' },
]}
searchTerm="foo"
/>
}
ReactDOM.render(
<Container />,
document.getElementById("root")
)
这个returns:
- 一个
- 阿福
- AfooA
- Foobar
- foobar foo
- Foobar Foo
- Afoo A Foobar
我发现了一些密切相关的问题,但还不够接近。我正在尝试仅设置搜索结果的搜索部分的样式。例如,如果查询是 "Thi", 我希望结果显示为 Things fall apart。我的问题是它在浏览器内部呈现 [object Object]。如何让它呈现所需的文本,以便我可以使用 CSS3 自由设置样式?我遇到的另一个问题是浏览器控制台中的警告
index.js:1 Warning: Each child in a list should have a unique "key" prop.
代码如下:
import React, { Fragment } from "react";
import CancelIcon from "@material-ui/icons/Cancel";
import CallMadeIcon from "@material-ui/icons/CallMade";
export default function SearchBar(props) {
return (
<Fragment>
<div className="search">
<div
className="search-input-container"
ref={props.searchInputContainerRef}
>
<label htmlFor="search-input"></label>
<input
type="text"
id="search-input"
placeholder={props.placeholder}
onChange={props.handleSetSearchTerm}
value={props.searchTerm}
ref={props.searchInputRef}
onFocus={props.blurAllOnSearch}
onBlur={props.blurAllOnSearch}
onKeyUp={props.handleFilter}
/>
{props.searchTerm === "" ? (
<button
ref={props.searchIconVectorRef}
type="button"
className="search-icon-btn"
onClick={props.focusSearchInput}
></button>
) : (
<CancelIcon
className="clear-btn"
type="button"
onClick={props.clearSearchInput}
/>
)}
<button className="go-search-btn">Go</button>
</div>
{props.searchResults.length !== 0 && (
<div className="search-results">
{props.searchResults.slice(0, 15).map((value, key) => {
const boldResultPart = (result, query) => {
let re = new RegExp(query, "ig");
return result
.replace(/- /g, "")
.replace(/\./g, "")
.replace(re, <span className="boldFont"> ${query} </span>); // <-- *My problem is this span renders as [object Object] in the browser*
};
let bolded = boldResultPart(value.title, props.searchTerm);
return (
<li className="data-item">
<a
className="result"
href={value.link}
target="_blank"
rel="noreferrer"
>
{bolded}
</a>
<CallMadeIcon className="call-made-icon" />
</li>
);
})}
</div>
)}
</div>
</Fragment>
);
}
替换会将您的 Span 转换为字符串。尝试根据正则表达式的结果创建跨度。这是一个例子:
function SearchBar(props) {
return <div>
{props?.searchResults.length && (
<div className="search-results">
{props.searchResults.slice(0, 15).map(value => {
const boldResultPart = (result, query) => {
let re = new RegExp(query, "ig");
let results = result.replace(/- /g, "")
.replace(/\./g, "")
.split(re);
return [results, [...(result.matchAll(re))].map(x => x[0])]
};
const [resultSplit, resultFind] = boldResultPart(value.title, props.searchTerm)
const makeBold = (q) => <strong className="boldFont">{q}</strong>
const bolded = resultSplit.map((i,c) => c ? <span key={c}>{makeBold(resultFind[c-1])}{i}</span> : i);
return (
<li key={value.title} className="data-item">
<a
className="result"
href={value.link}
target="_blank"
rel="noreferrer"
>
{bolded}
</a>
</li>
);
})}
</div>
)}
</div>
}
const Container = () => {
return <SearchBar
searchResults={[
{ title: '', link: '/fooa' },
{ title: 'A', link: '/fooa' },
{ title: 'Afoo', link: '/fooa' },
{ title: 'AfooA', link: '/fooa' },
{ title: 'Foobar', link: '/barbar' },
{ title: 'Foobar foo', link: '/barbar' },
{ title: 'Foobar Foo', link: '/barbar' },
{ title: 'Afoo A Foobar', link: '/barbar' },
]}
searchTerm="foo"
/>
}
ReactDOM.render(
<Container />,
document.getElementById("root")
)
这个returns:
- 一个
- 阿福
- AfooA
- Foobar
- foobar foo
- Foobar Foo
- Afoo A Foobar