react-router-dom Link导航后复选框状态未重置的解决方法
解决React路由跳转后筛选复选框状态未重置的问题
问题描述
我有一个SearchBar组件,点击其中的Link会跳转到ProductSearchScreen页面,展示对应分类的产品集合:
return ( <Link to={{ pathname: '/somepath', search: `searchItem=${category.name}` }}> {category.name} </Link> )
在ProductSearchScreen里设置了分类筛选复选框,但遇到一个问题:当我在category1页面勾选部分复选框后,通过搜索栏跳转到category2页面时,复选框依然保持选中状态——尽管新页面的URL参数里没有筛选条件,selectedCategories状态却没重置。
问题原因
Filters组件中selectedCategories的初始值仅在组件挂载时从queryParams获取一次。当路由参数(比如searchItem从category1变为category2)变化时,组件不会重新执行useState的初始化逻辑,导致状态保留了之前的选中值。
解决方案
通过监听路由参数变化,主动重置筛选状态,同时保持状态与URL参数同步:
1. 父组件传递关键参数
修改ProductSearchScreen,将当前分类和初始筛选分类传递给Filters组件,让子组件能感知路由变化:
function ProductSearchScreen() { const [products, setProducts] = useState([]); const [queryParams] = useSearchParams(); const currentCategory = queryParams.get('searchItem'); const initialCategories = queryParams.get('categories')?.split(','); const uniqueCategories = getUniqueCategories(products); // axios请求获取产品列表,更新products状态... // 修复分类筛选逻辑:返回布尔值判断是否保留产品 const filterCategories = (product) => { if(initialCategories?.length > 0) { return initialCategories.includes(product.category); } else { return true; } } const filteredAndSortedProducts = products?.filter(filterCategories); return ( <Filters uniqueCategories={uniqueCategories} currentCategory={currentCategory} initialCategories={initialCategories} /> ) }
2. 子组件监听参数变化并重置状态
修改Filters组件,添加useEffect监听currentCategory和initialCategories的变化,一旦参数更新就重置选中状态,同时确保操作复选框时同步更新URL参数:
function Filters({ uniqueCategories, currentCategory, initialCategories }) { const [queryParams, setQueryParams] = useSearchParams(); const [selectedCategories, setSelectedCategories] = useState(initialCategories ?? []); // 监听路由关键参数变化,重置选中状态 useEffect(() => { setSelectedCategories(initialCategories ?? []); }, [currentCategory, initialCategories]); const handleCategories = (category) => { let newSelected; if (selectedCategories.includes(category)) { newSelected = selectedCategories.filter((c) => c !== category); } else { newSelected = [...selectedCategories, category]; } setSelectedCategories(newSelected); // 同步更新URL中的筛选参数 const params = new URLSearchParams(queryParams); if (newSelected.length > 0) { params.set('categories', newSelected.join(',')); } else { params.delete('categories'); } setQueryParams(params); } return ( <> {uniqueCategories.map((category, index) => ( <div key={index} className="filter-type"> <input type="checkbox" disabled={initialCategories?.includes(category)} checked={selectedCategories.includes(category)} onChange={() => handleCategories(category)} /> <div className="filter-item">{category}</div> </div> ))} </> ) }
说明
- 当用户从
category1跳转到category2时,currentCategory发生变化,触发useEffect执行,将selectedCategories重置为新页面的初始筛选值(空数组),复选框恢复未选中状态。 - 修复了
filterCategories函数的逻辑错误:之前返回product会导致筛选失效,正确应该返回布尔值表示产品是否符合筛选条件。 - 操作复选框时同步更新URL参数,确保页面刷新或分享时筛选状态不会丢失。
内容的提问来源于stack exchange,提问作者Srivatsa
相关产品推荐
相关产品推荐

