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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 19:05:36