Как мне оформить часть моего искомого слова в React.js, например, смелее или светлее?

#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"); }