React搜索组件路由跳转问题:如何实现单次点击携带搜索内容跳转至指定路由
解决React搜索组件单次点击携带输入内容跳转路由的问题
你说得没错,问题根源就是React的useState更新是异步的——当你点击按钮调用onClick2时,setquery(x)并不会立刻把query更新成输入值,所以此时<Link>里的/web/${query}还是用的更新前的null,第一次点击自然跳转到了错误链接;第二次点击时query已经完成更新,所以能正常跳转,这就是需要双击的原因。
下面给你几个更优的解决方案,从简单到适合复杂场景:
方案1:直接用输入值跳转(最推荐,适合单纯搜索跳转)
其实我们根本不需要把输入值存在state里(除非你还有其他地方要用到这个状态),点击时直接获取输入框的值,用编程式导航跳转就行,完全避开state异步更新的问题:
import { useNavigate } from 'react-router-dom'; const Search = () => { const navigate = useNavigate(); // 拿到路由导航钩子 const handleSearch = () => { // 获取输入框的值并去除首尾空格 const inputValue = document.getElementById("navBarSearchForm").value.trim(); if(inputValue) { // 直接用输入值跳转,一步到位 navigate(`/web/${inputValue}`); } } return ( <div className="search"> <div className="input-group"> <input type="search" id="navBarSearchForm" className="form-control rounded" placeholder="Enter Website URL To Get Analytics" aria-label="Search" aria-describedby="search-addon" /> <button onClick={handleSearch} type="button" id="searchbutton" className="btn btn-outline-primary" > Search </button> </div> </div> ) } export default Search
这个方案单次点击就能生效,还比原来的代码简洁很多。
方案2:用state管理输入+useEffect监听跳转(适合需要维护输入状态的场景)
如果你需要把输入值存在state里(比如做实时搜索提示、输入校验),可以用useEffect监听query的变化,当query更新完成后再跳转:
import { useState, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; const Search = () => { const [query, setQuery] = useState(''); const navigate = useNavigate(); // 监听query的变化,更新完成后再跳转 useEffect(() => { if(query) { navigate(`/web/${query}`); // 可选:跳转后清空输入框和state,避免重复触发跳转 setQuery(''); document.getElementById("navBarSearchForm").value = ''; } }, [query, navigate]) // 实时同步输入框内容到state const handleInputChange = (e) => { setQuery(e.target.value.trim()); } const handleSearch = () => { const inputValue = document.getElementById("navBarSearchForm").value.trim(); if(inputValue) { setQuery(inputValue); } } return ( <div className="search"> <div className="input-group"> <input type="search" id="navBarSearchForm" className="form-control rounded" placeholder="Enter Website URL To Get Analytics" aria-label="Search" aria-describedby="search-addon" value={query} onChange={handleInputChange} /> <button onClick={handleSearch} type="button" id="searchbutton" className="btn btn-outline-primary" > Search </button> </div> </div> ) } export default Search
这个方案能保证跳转用的是最新的state值,同时满足你维护输入状态的需求。
额外优化:添加回车键触发搜索
给输入框加个回车键触发的功能,用户体验会更好:
<input // 其他属性不变 onKeyDown={(e) => { if(e.key === 'Enter') { handleSearch(); } }} />
内容的提问来源于stack exchange,提问作者devAR
相关产品推荐
相关产品推荐

