#javascript #reactjs #regex #search #replace
Вопрос:
Я нашел несколько тесно связанных вопросов, но не настолько близких. Я пытаюсь стилизовать только искомую часть результата поиска. Например, если запрос «Thi», я хочу, чтобы результат выглядел так, как будто они разваливаются. Моя проблема в том, что он отображает [объект объекта] прямо в браузере. Как сделать так, чтобы он отображал нужный текст и я мог свободно стилизовать его с помощью 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 amp;amp; (
<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>
);
}
Комментарии:
1. Каким был бы пример
props.searchResults
?2. Я передал результаты поиска через реквизиты родительского компонента, следовательно
props.searchResults
, это массив строк, которые возвращаются при поиске по данным сайта.3. Каково было бы содержимое этих переменных, были бы они примерно такими codepen.io/garaxer/pen/VwbJLwB
4. Да, что-то в этом роде. Но я хочу, чтобы первая буква оставалась заглавной. У меня также есть еще одно предупреждение в консоли браузера, в котором говорится
Warning: Each child in a list should have a unique "key" prop.
, что есть идеи, что это может означать?5. Я изменил свой ответ и код, чтобы первая буква поиска была прописной.
Ответ №1:
Замена преобразует ваш интервал в строку. Попробуйте создать интервал на основе результатов вашего регулярного выражения. Вот пример:
function SearchBar(props) {
return <div>
{props?.searchResults.length amp;amp; (
<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")
)
Это возвращает:
- A
- Афу
- Оооо
- Буфет
- Фубар фу
- Фубар Фу
- Ку-Ку, Буфет
Комментарии:
1. Спасибо Гэри за редактирование ответа. Могу я спросить, почему вы решили опустить « !== 0` в строке 1 нашего ответа?
props.searchResult
Переводится ли значение true в случае этого раздела кода? Пожалуйста, обратите внимание, что в моем коде это означает пустой массив, если нет результатов. Я хочу, чтобы этот конкретный div отображался только тогда, когда будут получены результаты поиска.2. Вы должны сохранить свой, я изменил его, чтобы мое окружение с помощью Typescript не выдавало ошибку, Это соответствовало бы вашим потребностям:
props?.searchResults.length amp;amp;
в этом уже нет необходимости!==0
[].length == false
3. Ладно, Гэри! Эй, не могли бы вы придумать лучший способ и в какой момент проверить, будет ли искомое слово находиться в начале определенного результата поиска, и если да, то только тогда первая буква должна быть заглавной, в противном случае оставьте поисковый запрос в нижнем регистре, если он попадает в предложение?
4. Спасибо тебе, Гэри, за комплимент и поддержку. Я изучаю компьютерные науки в Народном университете, а также получаю стипендию для разработчиков Google в Африке от Andela Google и Pluralsight. Я прохожу оплачиваемую стажировку в любом месте в качестве удаленного разработчика программного обеспечения. Не могли бы вы знать кого — нибудь, кто мог бы захотеть добавить меня в свою команду? Я был бы рад получить рекомендацию!
5. Привет, Гэри! Я хотел бы реализовать навигацию с помощью клавиш со стрелками вверх (код клавиши 38) и код клавиши 40 вниз по элементам списка и иметь возможность инициировать выбранную ссылку с помощью кода клавиши ввода 13 Как мне интегрировать этот код в ответ выше?
if (event.keyCode === 38 amp;amp; cursorPosition > 0) { setCursorPosition(cursorPosition - 1); console.log("up"); } else if ( event.keyCode === 40 amp;amp; cursorPosition < searchResults.length - 1 ) { setCursorPosition(cursorPosition 1); console.log("down"); }