React/react-router-dom:如何通过Link传递搜索查询数据
解决方案
要把导航栏的搜索查询传递到产品页面,核心是通过URL查询参数传递状态,再在产品页读取参数并过滤商品。下面分两步实现:
一、修改导航栏代码:传递搜索参数
你的现有代码存在两个问题:表单提交会触发页面刷新,且没有携带搜索参数。推荐两种实现方式:
方式1:用useNavigate处理表单提交(更符合表单场景)
import { useState } from 'react'; import { useNavigate } from 'react-router-dom'; // 你的导航组件 const Navbar = () => { const [query, setQuery] = useState(''); const navigate = useNavigate(); const handleSearch = (e) => { e.preventDefault(); // 阻止表单默认刷新行为 // 跳转到产品页,携带编码后的搜索参数 navigate(`/products?search=${encodeURIComponent(query)}`); }; return ( <form className="navSearch" onSubmit={handleSearch}> <input className="navInput" type="text" placeholder="Search for games" value={query} // 绑定值,变成受控组件 onChange={event => setQuery(event.target.value)} /> <button type="submit" className="navButton"> Search </button> </form> ); };
方式2:修改Link的to属性传递参数
如果坚持用Link,需阻止表单默认行为,并给to拼接查询参数:
import { useState } from 'react'; import { Link } from 'react-router-dom'; const Navbar = () => { const [query, setQuery] = useState(''); const handleSubmit = (e) => { e.preventDefault(); // 阻止页面刷新 }; return ( <form className="navSearch" onSubmit={handleSubmit}> <input className="navInput" type="text" placeholder="Search for games" value={query} onChange={event => setQuery(event.target.value)} /> <Link style={{textDecoration: 'none'}} to={`/products?search=${encodeURIComponent(query)}`} > <button type="button" className="navButton"> {/* 改成button类型,避免触发submit */} Search </button> </Link> </form> ); };
二、产品页面:读取参数并过滤商品
用react-router-dom的useSearchParams钩子(v6+版本)读取URL参数,再过滤商品列表:
import { useSearchParams } from 'react-router-dom'; import { useState, useEffect } from 'react'; const ProductsPage = () => { const [searchParams] = useSearchParams(); const [filteredProducts, setFilteredProducts] = useState([]); // 假设这是你的原始商品数据 const allProducts = [ { id: 1, name: "The Legend of Zelda" }, { id: 2, name: "Super Mario Odyssey" }, // ...更多商品 ]; useEffect(() => { // 获取搜索参数,为空则设空字符串 const searchQuery = searchParams.get('search') || ''; // 忽略大小写过滤商品(根据你的实际字段调整,比如name、description等) const filtered = allProducts.filter(product => product.name.toLowerCase().includes(searchQuery.toLowerCase()) ); setFilteredProducts(filtered); }, [searchParams, allProducts]); return ( <div className="products-container"> {filteredProducts.map(product => ( <div key={product.id} className="product-card"> <h3>{product.name}</h3> {/* 其他商品信息 */} </div> ))} </div> ); }; export default ProductsPage;
关键细节说明
- 用
encodeURIComponent编码查询参数:避免空格、中文等特殊字符导致URL解析错误。 - 受控组件:给input加上
value={query},确保输入状态和组件状态同步。 - 版本兼容:如果是
react-router-dom v5,可以用useLocation替代useSearchParams:import { useLocation } from 'react-router-dom'; // ... const location = useLocation(); const searchQuery = new URLSearchParams(location.search).get('search') || '';
内容的提问来源于stack exchange,提问作者torrey pines
相关产品推荐
相关产品推荐

