React应用:如何阻止搜索框为空时结果Div自动填充数据?
解决方法
要实现仅在用户输入搜索内容后才加载卡牌数据,需要做以下关键修改:
1. 阻止空搜索时的请求触发
当前组件挂载或搜索框为空时,useEffect会自动发起请求导致加载随机卡牌。我们需要添加判断逻辑,仅当搜索输入有有效内容时才调用接口。
2. 清空空搜索状态下的卡牌数据
当用户清空搜索框时,重置卡牌状态为空数组,避免显示历史搜索结果。
修改后的完整代码
import { useState, useEffect, useRef } from "react"; import CardOverview from "../components/CardOverview"; import styles from "./SearchCards.module.css"; import Select from "react-select"; import setOptions from "../data/sets"; import SpinnerOverride from "../utils/SpinnerOverride"; import SetOverview from "../components/SetOverview"; export default function Search() { const [loading, setLoading] = useState(false); const [searchInput, setSearchInput] = useState(""); const [set, setSet] = useState(null); const [cards, setCards] = useState([]); const isMounted = useRef(true); const SEARCH_CARDS_BASE_URL = "https://api.pokemontcg.io/v2/cards"; useEffect(() => { async function fetchCards() { setLoading(true); const cleanSearchInput = searchInput.toLowerCase().trim(); let url = `${SEARCH_CARDS_BASE_URL}?`; if (set && set.value !== "all") { url += `q=set.id:${set.value}`; if (cleanSearchInput !== "") { url += ` name:${cleanSearchInput}`; } } else { if (cleanSearchInput !== "") { url += `q=name:${cleanSearchInput}`; } } console.log(url); const resp = await fetch(url); const cards = await resp.json(); setCards(cards.data); setTimeout(() => { setLoading(false); }, 3000); } const cleanSearchInput = searchInput.toLowerCase().trim(); // 仅当搜索输入不为空时发起请求 if (cleanSearchInput !== "") { fetchCards(); } else { // 搜索输入为空时清空卡牌数据,结束加载状态 setCards([]); setLoading(false); } }, [searchInput, set]); return ( <div> <h1 className={styles.header}>Search Pokemon</h1> <input className={styles.searchInput} type="text" value={searchInput} onChange={(e) => setSearchInput(e.target.value)} placeholder={"e.g. Pikachu"} /> <Select className={styles.setFilter} defaultValue={setOptions[0]} onChange={(newSet) => setSet(newSet)} name="set" options={setOptions} classNamePrefix="select" /> {loading ? ( <SpinnerOverride /> ) : !loading && cards.length === 0 ? ( <SetOverview /> ) : ( <div className={styles.flexboxContainer}> {cards.map((card, idx) => { return ( <div key={idx}> <CardOverview cardData={card} /> </div> ); })} </div> )} </div> ); }
核心修改说明
- 在
useEffect中新增输入内容校验,只有当搜索框有非空内容时才执行fetchCards。 - 搜索框清空时,主动重置
cards状态为空数组,并关闭加载状态,确保页面显示初始的SetOverview组件。 - 移除了原代码中未实际生效的
isMounted赋值逻辑,简化代码结构。
内容的提问来源于stack exchange,提问作者Zach Delapenha
相关产品推荐
相关产品推荐

