基礎篩選器

import React, { ChangeEvent, useState } from "react";

export default function Filter() {
  const [input, setInput] = useState<string>(""); // 儲存使用者輸入
  const [filteredContent, setFilteredContent] = useState<string | null>(null); // 篩選後的內容

  const data = [
    { id: 0, content: "這是 0" },
    { id: 1, content: "這是 1" },
    { id: 2, content: "這是 2" },
  ];

  const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {
    const value = event.target.value;
    setInput(value);

    const number = parseInt(value, 10);
    if (!isNaN(number)) {
      const result = data.find((item) => item.id === number);
      setFilteredContent(result ? result.content : "找不到對應內容");
    } else {
      setFilteredContent("請輸入有效的數字");
    }
  };

  return (
    <div>
      <h2>數字篩選器</h2>
      <input
        type="text"
        placeholder="輸入數字 (例如 113)"
        value={input}
        onChange={handleInputChange}
      />
      <div style={{ marginTop: "10px" }}>
        <strong>結果:</strong> {filteredContent}
      </div>
    </div>
  );
};

說明:

parseInt(target , 10) : 將target轉為10進位數字

ChangeEvent<HTMLInputElement> : 因為onChange接收的type為ChangeEvent<HTMLInputElement>

所以後面還要再const value = event.target.value;單獨取出值

關鍵字查詢

使用.filter() 根據useState內容來篩選 (filter詳細內容可以看JavaScript Notion)

JavaScript

import { useState } from 'react';

export default function FilterableList() {
  const [search, setSearch] = useState('');

  const data = [
    { id: 1, title: '蘋果', description: '紅色的水果,含有維生素C' },
    { id: 2, title: '香蕉', description: '黃色的水果,富含鉀' },
    { id: 3, title: '橘子', description: '橙色的水果,酸甜可口' },
  ];

  // filter
  const filteredData = data.filter(
    (item) =>
      item.title.includes(search) || item.description.includes(search) // 搜尋標題或描述
  );//includes(target) target是否在該字串中

  return (
    <div>
      <h1>關鍵字搜尋</h1>
      <input
        type="text"
        placeholder="輸入關鍵字"
        value={search}
        onChange={(e) => setSearch(e.target.value)} // 更新搜尋字串
        style={{ marginBottom: '20px', padding: '10px', width: '300px' }}
      />

      <ul>
        {filteredData.map((item) => (
          <li key={item.id} style={{ marginBottom: '10px' }}>
            <h3>{item.title}</h3>
            <p>{item.description}</p>
          </li>
        ))}
      </ul>
      
      {/* 無輸入或找不到匹配的,filterData就會lenght == 0 */}
      {filteredData.length === 0 && <p>沒有符合的結果</p>}
    </div>
  );
}

Input 動態篩選

輸入”1”時,出現”1的99乘法表”


先在components資料夾下創一個資料夾放篩選出來的檔案

ex: components > number > 1.tsx

//1.tsx
export default function CourseItems() {
  // 生成 99 乘法表的data
  const multiplicationTable = Array.from({ length: 1 }, (_, i) =>
    Array.from({ length: 9 }, (_, j) => `${i + 1} x ${j + 1} = ${(i + 1) * (j + 1)}`)
  );

  return (
    <section>
      <h2>1的99 乘法表</h2>
      <div>
        {multiplicationTable.map((row, index) => (
          <div key={index}>
            {row.map((item, subIndex) => (
              <p key={subIndex}>{item}</p>
            ))}
          </div>
        ))}
      </div>
    </section>
  );
}

說明:

.from() : 創建一個指定長度的陣列,並且可以使用第二個參數來設置每個元素的值。

主程式

//主程式
import { useState, Suspense, ChangeEvent, FC } from 'react';

export default function CourseItems() {
  const [input, setInput] = useState<string>(''); 
  const [ContentComponent, setContentComponent] = useState<FC | null>(null); 
  // 動態匯入的元件

  const handleInputChange = async (event: ChangeEvent<HTMLInputElement>) => {
  //h...函式是只有監聽對象發生改變才會被觸發,無法主動呼叫(後面會詳述)
  
    const value = event.target.value; // 取得輸入值
    setInput(value);

    const v = parseInt(value, 10); // 將字串轉換為整數

    if (!isNaN(v)) {
      try {
        // 動態匯入對應的檔案
        const module = await import(`@/components/number/${v}.tsx`);
        if (module.default) {
          setContentComponent(() => module.default);
        } else {
          console.error('模組沒有 default 導出');
          setContentComponent(() => null);
        }
      } catch (error) {
        console.error('無法找到對應檔案', error);
        setContentComponent(() => null);
      }
    } else {
      setContentComponent(null); // 清空元件
    }
  };

  return (
    <section>
      <h2>乘法表</h2>
      <input
        type="text"
        placeholder="輸入正整數"
        value={input}
        onChange={handleInputChange}
      />
      <div style={{ marginTop: '20px' }}>
        <Suspense fallback={<div>載入中...</div>}>
          {ContentComponent ? (
            <ContentComponent />
          ) : ''}
        </Suspense>
      </div>
    </section>
  );
}