React开发:如何实现仅点击提交按钮更新搜索展示,输入变更不触发更新
问题原因
现有代码逻辑存在两点问题导致不符合预期:
- 过滤逻辑写在了依赖
search、calendars的useEffect中,只要search状态变化就会自动更新过滤结果,当display被设为true后新的过滤结果会直接实时渲染 - 输入框事件绑定错误:
input元素本身不存在onSubmit事件,你当前的写法无法正常同步用户输入内容到search状态,你遇到的输入实时生效的情况,大概率是实际代码中错误把setSearch绑定到了输入框的onChange事件上。
调整方案
我们调整状态分层逻辑,把用户实时输入和正式搜索关键词拆分为两个状态,仅在提交时触发过滤:
- 新增
searchInput状态存储用户实时输入的内容 - 移除自动触发过滤的
useEffect,将过滤逻辑移到表单提交方法内 - 修正输入框的事件绑定
调整后完整代码
import { useState, useEffect } from 'react'; import { BsSearch } from 'react-icons/bs'; import Form from 'react-bootstrap/Form'; import Button from 'react-bootstrap/Button'; import Calendar from './Calendar'; // 请根据你的实际文件路径调整 function Schedule(props){ // 存储全量日历数据 const [calendars,setCalendars] = useState([]) // 存储用户输入框的实时内容 const [searchInput, setSearchInput] = useState(""); // 加载状态 const [loading, setLoading] = useState(false); // 控制是否展示搜索结果 const [display, setDisplay] = useState(false); // 存储过滤后的日历数据 const [filteredCalendars, setFilteredCalendars] = useState([]); // 初始化拉取全量日历数据 useEffect(()=>{ setLoading(true); fetch('data/scheduled_playlist.json',{ headers:{ 'Content-Type': 'application/json', 'Accept': 'application/json' } }).then(function(response){ return response.json() }).then(function(jsonCalendars){ setCalendars(jsonCalendars) setLoading(false); }) }, []) if (loading) { return <p>Loading calendars...</p>; } // 表单提交逻辑:仅提交时才执行过滤 function handleSubmit(e) { e.preventDefault(); // 提交时才基于当前输入内容过滤 const filtered = calendars.filter( calendar => calendar.storeID.toString().startsWith(searchInput) ); setFilteredCalendars(filtered); setDisplay(true); } let result = ""; if (display) { result = <div> {filteredCalendars.map((calendar) => ( <Calendar key={calendar.storeID} calendar={calendar}/> ))} </div> } return( <div> <div className="text-center"> <h1>Schedule Playlists</h1> </div> <Form onSubmit={handleSubmit}> <div className="search-box"> <BsSearch/> <input type="text" placeholder="Search calendar by store ID..." value={searchInput} onChange={(e) => setSearchInput(e.target.value)} /> <Button type="submit">Submit form</Button> </div> </Form> <div> {result} </div> </div> ) } export default Schedule
注:代码里补充了列表渲染必填的
key属性,避免React报错,你可以根据实际业务字段调整key的取值。
内容的提问来源于stack exchange,提问作者Diane Batres
相关产品推荐
相关产品推荐

