You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.12 11:42:04