在React中使用indexOf突出显示搜索词

问题描述 投票:0回答:2

我有一个搜索组件,它根据 searchTerm 从 SlideData 返回数据。我的目标是突出显示输入的单词。我想我需要使用indexOf或标签,但我正在努力思考在哪里使用它的逻辑?为了清楚起见,预期的结果是,如果我搜索“汉堡包”,它将显示带有汉堡包的所有结果,并在这些结果中突出显示“汉堡包”。

const [searchTerm, setSearchTerm] = useState("");
const SlideData = [
  {
    slideIndex: 1,
    title: "My name is Bob",
    text1: "Bob likes to eat hamburgers",
    text2: "Kenny likes to eat hot dogs",
    text3: "Terry likes milkshakes"
  },
  {
    slideIndex: 2,
    title: "My name is Jill",
    text1: "Jill likes to eat hamburgers",
    text2: "Joshua likes to eat hot dogs",
    text3: "Steven likes milkshakes"
  }
]
<div className="search-results">
          <ul className="search-list">
            {SlideData.filter((item) => {
              if (searchTerm === "") {
                return null;
              } else {
                //concat the text properties into variable//
                let searchText = item.title + item.text1 + item.text2 + item.text3 + item.text4;
                //if the variable contains the search term value//
                if (searchText.toLowerCase().includes(searchTerm.toLowerCase())) {
                  //return those items//
                  return item;
                }
              }
          
            }).map((item) => (
              //map through the items and display list of results
              <div key={item.slideIndex} style={{ marginTop: "20px" }}>
                <h4 style={{ color: "white" }}>{item.title}</h4>
                <li className="search-item">{item.text1}</li>
                <li className="search-item">{item.text1.indexOf(searchTerm)}</li>
                <a
                  className="search-link"
                  onClick={() => {
                    context.setCurrentSlide(item.slideIndex);
                    setSearchTerm("");
                  }}
                >
                  Go To Slide {item.slideIndex}
                </a>
              </div>
            ))}
          </ul>
        </div>

我正在尝试的事情



        //find the search term in the results//
              const highlighted = item.text1.indexOf(searchTerm);
              if(searchTerm === -1){
                //highlight the term
              }else{
                //Do nothing
              }
reactjs search highlight indexof
2个回答
1
投票

为了使用不同的样式来定位结果,您需要将其分解为自己的 HTML 元素。

您可以使用这个正则表达式函数

const splitResult = (result) =>
//Split on search result and then simply style the matches
result.split(new RegExp(`(${searchTerm})`, `gi`)).map((piece, index) => {
  return (
    <span
      key={index}
      style={{
        background:
          piece.toLowerCase() === searchTerm.toLocaleLowerCase()
            ? "YELLOW"
            : "TRANSPARENT"
      }}
    >
      {piece}
    </span>
  );
});

这是您的完整组件,我删除了一些与问题无关的部分

export default function App() {
  const [searchTerm, setSearchTerm] = useState("");

  const splitResult = (result) =>
    //Split on search result and then simply style the matches then map through
    result.split(new RegExp(`(${searchTerm})`, `gi`)).map((piece, index) => {
      return (
        <span
          key={index}
          style={{
            background:
              piece.toLowerCase() === searchTerm.toLocaleLowerCase()
                ? "YELLOW"
                : "TRANSPARENT"
          }}
        >
          {piece}
        </span>
       );
     });

   return (
     <div className="search-results">
       <ul className="search-list">
         {/** Search input */}
         <input
           type="search"
           value={searchTerm}
           onChange={(e) => setSearchTerm(e.target.value)}
         />
         {SlideData.filter((item) => {
           if (searchTerm === "") {
             return null;
           } else {
            //concat the text properties into variable//
             let searchText = item.title + item.text1 + item.text2 + item.text3 + item.text4;
            //if the variable contains the search term value//
            if (searchText.toLowerCase().includes(searchTerm.toLowerCase())) {
               //return those items//
               return item;
            }
          }
          return null;
         }).map((item) => (
          //map through the items and display list of results
          <div key={item.slideIndex} style={{ marginTop: "20px" }}>
            <h4>{item.title}</h4>
            <li>{splitResult(item.text1)}</li>
            <li>{item.text1.indexOf(searchTerm)}</li>
          </div>
        ))}
      </ul>
    </div>
  );
}

0
投票

我将使用原生的 CSS 自定义突出显示 API 以命令式方式执行此操作。优点是 DOM 不会因选择而修改,不涉及 React,并且除了

useEffect
:

之外不需要任何其他逻辑
import { useEffect, useState } from "react";
import { highlightSearchTerm } from "highlight-search-term";

export default function App() {
  const [search, setSearch] = useState("");
  useEffect(() => {
    highlightSearchTerm({ search, selector: ".search-results" });
  }, [search]);
  return (
    <div>
      <input
        type="text"
        value={search}
        onChange={(e) => setSearch(e.target.value)}
      />
      <div className="search-results">
        Lorem ipsum dolor sit amet, consectetur adipiscing elit.
      </div>
    </div>
  );
}
© www.soinside.com 2019 - 2024. All rights reserved.