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

React使用react-router-dom存储筛选参数时浏览器返回功能失效

异常原因

  • 多余的popstate事件监听逻辑导致点击返回时多回退多层历史记录:popstate事件本身就是用户点击浏览器返回/前进按钮触发的系统事件,你在回调里额外调用history.goBack(),相当于每次点返回会执行两次回退操作。如果你的筛选页在历史栈里有效记录较少,两次回退就会直接跳出筛选页回到浏览器主页。
  • 没有同步路由参数到本地筛选状态:当点击返回导致location.search变化时,你本地的Standard/Hobbies/Responsibility三个状态没有从最新的路由参数里取值,就算回退成功,页面也不会显示上一次的筛选条件。
  • 组件初始化时冗余的history.push操作:只要组件挂载,依赖QueryString的useEffect就会执行一次history.push,相当于刚进页面就多压了一条相同的历史记录,拉长了历史栈,放大了第一个问题的影响。
  • 手动维护QueryString状态属于多余逻辑:路由的location.search本身就是唯一的数据源,额外用state存一份反而会导致数据不同步。

修复方案

  1. 删掉所有手动监听popstate的代码,react-router已经内置了历史记录管理,不需要自己额外处理。
  2. 以location.search作为唯一的数据源,组件挂载和location变化时,都从路由参数里解析出筛选值同步到本地state。
  3. 点击应用按钮时直接调用history.push更新路由,不需要额外维护QueryString状态。
  4. 受控组件不需要同时设置defaultValue和value,删掉多余的defaultValue属性避免冲突。

修复后代码如下:

import React, {useState, useEffect} from 'react'
import {DropDownList, MultiSelect} from "@progress/kendo-react-dropdowns"
import {Button} from '@progress/kendo-react-buttons'
import { useHistory, useLocation } from "react-router-dom"

const Filter = () => {
    const history=useHistory()
    const location=useLocation()
    const [Standard,setStandard] = useState("All")
    const [Hobbies,setHobbies] = useState(["Playing"])
    const [Responsibility,setResponsibility] = useState("All")

    const options={
        StandardList:["All","VI","VII","VIII"],
        HobbiesList: ["Playing", "Drawing","Swimming"],
        ResponsibilityList:["All","Monitor","Head","Sports Captain"]
    }

    // 路由参数变化时同步到本地state
    useEffect(() => {
        const params = new URLSearchParams(location.search)
        if (params.get('Standard')) {
            setStandard(JSON.parse(params.get('Standard')))
        }
        if (params.get('Responsibility')) {
            setResponsibility(JSON.parse(params.get('Responsibility')))
        }
        if (params.get('IncidentStatus')) {
            setHobbies(JSON.parse(params.get('IncidentStatus')))
        }
    }, [location.search])

    const handleApply = () => {
        const params = new URLSearchParams()
        params.set('Standard', JSON.stringify(Standard))
        params.set('Responsibility', JSON.stringify(Responsibility))
        params.set('IncidentStatus', JSON.stringify(Hobbies))
        history.push({ search: params.toString() })
    }

    return (
        <div>
            <label>Standard </label>
            <DropDownList data={options.StandardList} value={Standard} 
            onChange={(event)=>setStandard(event.target.value)}/> 

            <label > Hobbies </label>
            <MultiSelect data={options.HobbiesList} value={Hobbies} onChange={(event)=>setHobbies([...event.value])}/>
        
            <label > Responsibility </label>
            <DropDownList data= {options.ResponsibilityList} value={Responsibility} onChange={(event)=>setResponsibility(event.target.value)} />

            <Button id="submitFilter" type="button" onClick={handleApply} > Apply </Button>   
        </div>
    )  
}

export default Filter

内容的提问来源于stack exchange,提问作者Chaya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 05:54:03