React中实现最多存储5条记录的搜索历史数组展示
问题根因
- 原逻辑中
setSearchHistory(search)直接将字符串类型的单次搜索值赋值给数组类型的状态,每次点击都会覆盖原有内容,无法留存历史记录 - 渲染位置直接输出数组变量,既没有做长度截断控制最多5条,也没有做格式化展示处理
修复方案
1. 调整历史记录存储逻辑
修改点击事件的状态更新代码,利用状态更新的回调函数拿到上一次的历史数组,将新搜索词插到数组头部后截取前5位,保证最多只存最近5条记录,同时增加空值判断避免存入空内容:
const handleClick = event => { event.preventDefault(); // 空输入不存入历史 if (!search.trim()) return; setSearchHistory(prevHistory => { // 新搜索词放最前,拼接旧历史后截取前5条 return [search, ...prevHistory].slice(0, 5); }); };
如果需要避免重复记录,可以先过滤掉旧历史里和当前搜索词相同的项再拼接:
return [search, ...prevHistory.filter(item => item !== search)].slice(0,5)
2. 调整历史记录渲染逻辑
不要直接在JSX里输出数组,根据需求选择列表渲染或者文本拼接的方式展示:
- 如果要做斜杠分隔的文本展示:
<h3 className="tempmin_max"> History: {searchHistory.length ? searchHistory.join(' / ') : '暂无搜索记录'} </h3>
- 如果要做列表展示:
<h3 className="tempmin_max"> History: <ul style={{margin: '8px 0', paddingLeft: 20}}> {searchHistory.map((record, index) => ( <li key={index}>{record}</li> ))} </ul> </h3>
修复后完整代码
import { useState, useEffect } from 'react'; const Tempapp = () => { const [city, setCity] = useState(null); const [search, setSearch] = useState("Dehradun"); const [searchHistory, setSearchHistory] = useState([]); useEffect(() => { const fetchApi = async () => { const url = `https://api.openweathermap.org/data/2.5/weather?q=${search}&units=metric&appid=7938d9005e68d8b258a109c716436c91` const response = await fetch(url); const resJson = await response.json(); setCity(resJson.main); }; fetchApi(); }, [search]) const handleClick = event => { event.preventDefault(); if (!search.trim()) return; setSearchHistory(prev => [search, ...prev].slice(0,5)); }; return ( <> <div className="box"> <div className="inputData"> <input id="btnc" type="search" value={search} className="inputFeild" onChange={(event) => { setSearch(event.target.value) }} /> <button onClick={handleClick}>Click</button> </div> <input className="is"></input> <h3 className="tempmin_max"> History: {searchHistory.length ? searchHistory.join(' / ') : '暂无搜索记录'} </h3> {!city ? ( <p className="errorMsg">Enter City Name</p> ) : ( <div> <div className="info"> <h2 className="location"> <i className="fa-solid fa-street-view"> </i>{search} </h2> <h1 className="temp"> {city.temp} </h1> <h3 className="tempmin_max"> Min : {city.temp_min} | Max : {city.temp_max} </h3> </div> <div className="wave -one"></div> <div className="wave -two"></div> <div className="wave -three"></div> </div> )} </div> </> ) } export default Tempapp;
内容的提问来源于stack exchange,提问作者Nitin Gaur
相关产品推荐
相关产品推荐

