Here's an overview of what I've tried so far:
Filter data function
function filterData(searchText, restaurants) { const filterData = restaurants.filter((restaurant) => restaurant.info.name.includes(searchText) ); return filterData; }
import { restruntList } from "../constants"; // JSON数据 const Body = () => { const [searchText, setSearchText] = useState(""); const [restaurants, setRestaurants] = useState(restruntList); return ( <> <div className="search-container"> <input type="text" className="search-input" placeholder="搜索" value={searchText} onChange={(e) => { setSearchText(e.target.value); }} /> <button className="search-btn" onClick={() => { //过滤数据 const data = filterData(searchText, restaurants); //更新状态 - restaurant变量 setRestaurants(data); }} > 搜索{" "} </button> </div> //UI <div className="restrunt-list"> {restruntList.map((restaurant) => { return <RestruntCard {...restaurant.info} key={restaurant.info.id} />; })} </div> </> ); };
restruntList JSON data format
export const restruntList = [ { info: { id: "23719", name: "麦当劳", cloudinaryImageId: "ee5f8e06b300efc07c9fe3f4df40dfc4", locality: "JM Road", areaName: "Shivajinagar", costForTwo: "₹400 for two", cuisines: ["汉堡", "饮料", "咖啡馆", "甜点"], avgRating: 4.3, } } ]
P粉8659009942023-09-21 00:18:34
Based on the code and description you provided, this approach looks mostly correct, but there is a small issue with the way the filter data function and restaurant data are handled.
The main problem is how you handle filtering and updating status. Since React's status updates are asynchronous, directly using the searchText
value to filter restaurants
may not yield the expected results. Status updates may not happen immediately after setting searchText
, so you may get inconsistent or stale filtered results.
To solve this problem, you can utilize the useEffect
hook to update the filtered data when searchText
changes. This way the filter function will always operate on the latest state. Here is the updated code:
import React, { useState, useEffect } from 'react'; import { restruntList } from '../constants'; function filterData(searchText, restaurants) { const filteredData = restaurants.filter((restaurant) => restaurant.info.name.toLowerCase().includes(searchText.toLowerCase()) ); return filteredData; } const Body = () => { const [searchText, setSearchText] = useState(''); const [filteredRestaurants, setFilteredRestaurants] = useState(restruntList); useEffect(() => { const data = filterData(searchText, restruntList); setFilteredRestaurants(data); }, [searchText]); return ( <> <div className="search-container"> <input type="text" className="search-input" placeholder="搜索" value={searchText} onChange={(e) => setSearchText(e.target.value)} /> </div> <div className="restaurant-list"> {filteredRestaurants.map((restaurant) => ( <RestruntCard {...restaurant.info} key={restaurant.info.id} /> ))} </div> </> ); }; export default Body;
Changes in code:
restaurants
to filteredRestaurants
to avoid confusion between raw and filtered data. useEffect
hook to handle filtering when searchText
changes. This ensures correct updates of filtered data. Now, as you type in the search input box, the filtering should take effect immediately and the restaurant list should be updated accordingly.