Ionic React 试图实现一个过滤搜索栏以按标题过滤预制列表

Ionic React trying to implement a filtering search bar to filter pre made lists by their title

我一直在苦苦思索如何在我的 Ionic 应用程序中创建搜索栏。当我试图找出如何创建搜索栏时,我只找到 Angular 与 Ionic 的示例,不幸的是,Ionic 文档上的 React 示例没有帮助。此外,当我只是简单地搜索如何使用 React 和 Typescript 来实现时,我总是陷入死胡同。我似乎无法理解如何实现搜索栏以允许用户输入标题,然后该标题只会单独显示该卡片。如果能找到解决此问题的方法,我们将不胜感激。

import React, { useState } from "react";
import {
  IonHeader,
  IonContent,
  IonToolbar,
  IonTitle,
  IonPage,
  IonButton,
  IonCard,
  IonCardHeader,
  IonCardSubtitle,
  IonCardTitle,
  IonCardContent,
  IonGrid,
  IonRow,
  IonCol,
  IonItem,
  IonLabel,
  IonFooter,
  IonModal,
  IonIcon,
  IonSearchbar,
} from "@ionic/react";

export const SEARCH = [
  {
    id: "s1",
    title: "Business",
    detail:
      "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English.",
    page: "/search-business",
  },
  {
    id: "s2",
    title: "Computing",
    detail:
      "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English.",
    page: "/search-computing",
  },
  {
    id: "s3",
    title: "Connections",
    detail:
      "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English.",
    page: "/search-connections",
  },
  {
    id: "s4",
    title: "Construction",
    detail:
      "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English.",
    page: "/search-construction",
  },
  {
    id: "s5",
    title: "Engineering",
    detail:
      "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English.",
    page: "/search-engineering",
  },
  {
    id: "s6",
    title: "Graduate",
    detail:
      "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English.",
    page: "/search-graduate",
  },
  {
    id: "s7",
    title: "Marketing",
    detail:
      "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English.",
    page: "/search-marketing",
  },
  {
    id: "s8",
    title: "Medicine",
    detail:
      "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English.",
    page: "/search-medicine",
  },
  {
    id: "s9",
    title: "Science",
    detail:
      "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English.",
    page: "/search-science",
  },
];

export const Search: React.FC = () => {
  const [showModal, setShowModal] = useState(false);

  return (
    <IonPage>
      <IonHeader>
        <IonToolbar>
          <IonTitle>Search</IonTitle>
        </IonToolbar>
        <IonToolbar>
          <IonSearchbar>
            
          </IonSearchbar>
        </IonToolbar>
      </IonHeader>
      <IonContent className="ion-padding">
        <IonGrid>
          <IonRow>
            {SEARCH.map((search) => (
              <IonCol
                size="12"
                size-xs="12"
                size-sm="6"
                size-md="4"
                size-lg="4"
                key={search.id}
              >
                <IonCard>
                  <IonCardHeader>
                    <IonCardTitle>{search.title}</IonCardTitle>
                    <IonCardSubtitle>Sector</IonCardSubtitle>
                  </IonCardHeader>
                  <IonCardContent>{search.detail}</IonCardContent>
                  <IonFooter className="ion-text-right">
                    <IonButton
                      color="secondary"
                      fill="clear"
                      routerLink={search.page}
                    >
                      View
                    </IonButton>
                  </IonFooter>
                </IonCard>
              </IonCol>
            ))}
            <IonCol className="ion-text-center">
              <IonModal isOpen={showModal} cssClass="my-custom-class">
                <p>This is modal content</p>
                <IonButton
                  color="secondary"
                  onClick={() => setShowModal(false)}
                >
                  Close Modal
                </IonButton>
              </IonModal>
              <IonButton color="secondary" onClick={() => setShowModal(true)}>
                Information
              </IonButton>
            </IonCol>
          </IonRow>
        </IonGrid>
      </IonContent>
    </IonPage>
  );
};

export default Search;

您应该在内部使用事件 onIonChange 来获取值搜索和过滤数据。

const [searchText, setSearchText] = useState('');

useEffect(() => {
   // filter here
}, [searchText])

<IonSearchbar value={searchText} onIonChange={e => setSearchText(e.detail.value!)}></IonSearchbar>

正如 Cuong Manh Nguyen 所指出的,您需要在搜索栏上添加 onIonChange 并在搜索查询更改时过滤搜索数组

import React, { useState, useEffect } from "react";
import {
  IonHeader,
  IonContent,
  IonToolbar,
  IonTitle,
  IonPage,
  IonButton,
  IonCard,
  IonCardHeader,
  IonCardSubtitle,
  IonCardTitle,
  IonCardContent,
  IonGrid,
  IonRow,
  IonCol,
  IonItem,
  IonLabel,
  IonFooter,
  IonModal,
  IonIcon,
  IonSearchbar,
} from "@ionic/react";

export const SEARCH = [
  {
    id: "s1",
    title: "Business",
    detail:
      "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English.",
    page: "/search-business",
  },
  {
    id: "s2",
    title: "Computing",
    detail:
      "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English.",
    page: "/search-computing",
  },
  {
    id: "s3",
    title: "Connections",
    detail:
      "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English.",
    page: "/search-connections",
  },
  {
    id: "s4",
    title: "Construction",
    detail:
      "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English.",
    page: "/search-construction",
  },
  {
    id: "s5",
    title: "Engineering",
    detail:
      "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English.",
    page: "/search-engineering",
  },
  {
    id: "s6",
    title: "Graduate",
    detail:
      "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English.",
    page: "/search-graduate",
  },
  {
    id: "s7",
    title: "Marketing",
    detail:
      "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English.",
    page: "/search-marketing",
  },
  {
    id: "s8",
    title: "Medicine",
    detail:
      "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English.",
    page: "/search-medicine",
  },
  {
    id: "s9",
    title: "Science",
    detail:
      "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English.",
    page: "/search-science",
  },
];

export const Search: React.FC = () => {
  const [showModal, setShowModal] = useState(false);
  const [searchQuery, setSearchQuery] = useState('');
  const [filteredSearch, setFilteredSearch] = useState([
  {
    id: "",
    title: "",
    detail: "",
    page: "",
  }])

useEffect(() => {
    let tempSearchResult = SEARCH.filter(ele => ele.title.includes(searchQuery))
    setFilteredSearch([...tempSearchResult])
},[searchQuery])

  return (
    <IonPage>
      <IonHeader>
        <IonToolbar>
          <IonTitle>Search</IonTitle>
        </IonToolbar>
        <IonToolbar>
          <IonSearchbar value={searchQuery} onIonChange={e => setSearchQuery(e.detail.value!) >
            
          </IonSearchbar>
        </IonToolbar>
      </IonHeader>
      <IonContent className="ion-padding">
        <IonGrid>
          <IonRow>
            {filteredSearch.map((search) => (
              <IonCol
                size="12"
                size-xs="12"
                size-sm="6"
                size-md="4"
                size-lg="4"
                key={search.id}
              >
                <IonCard>
                  <IonCardHeader>
                    <IonCardTitle>{search.title}</IonCardTitle>
                    <IonCardSubtitle>Sector</IonCardSubtitle>
                  </IonCardHeader>
                  <IonCardContent>{search.detail}</IonCardContent>
                  <IonFooter className="ion-text-right">
                    <IonButton
                      color="secondary"
                      fill="clear"
                      routerLink={search.page}
                    >
                      View
                    </IonButton>
                  </IonFooter>
                </IonCard>
              </IonCol>
            ))}
            <IonCol className="ion-text-center">
              <IonModal isOpen={showModal} cssClass="my-custom-class">
                <p>This is modal content</p>
                <IonButton
                  color="secondary"
                  onClick={() => setShowModal(false)}
                >
                  Close Modal
                </IonButton>
              </IonModal>
              <IonButton color="secondary" onClick={() => setShowModal(true)}>
                Information
              </IonButton>
            </IonCol>
          </IonRow>
        </IonGrid>
      </IonContent>
    </IonPage>
  );
};

export default Search;