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

Next.js中删除sessionStorage值时Input的onChange事件不触发

问题分析与解决方案

问题出在SSR(服务端渲染)场景下的 hydration 不匹配:你的自定义Hook在服务端渲染时,useState的初始化函数因为不存在window会返回undefined,导致服务端输出的输入框value为空;但客户端hydration时,会读取sessionStorage并将state更新为defaultValue或存储值,这就造成了React预期的DOM状态和实际渲染状态不一致。这种不匹配会干扰输入框的事件监听逻辑,导致首次删除全部内容时onChange无法正常触发。

修改后的自定义Hook代码

export const useSessionStorage = (hookProps) => {
    const { key, defaultValue } = hookProps

    // 服务端和客户端初始值统一为defaultValue,避免hydration不匹配
    const [sessionItem, setSessionItem] = useState(defaultValue)

    // 客户端挂载后读取sessionStorage,更新state
    useEffect(() => {
        const storedItem = sessionStorage.getItem(key)
        if (storedItem !== null) {
            try {
                setSessionItem(JSON.parse(storedItem))
            } catch (e) {
                // 解析失败 fallback 到默认值
                setSessionItem(defaultValue)
            }
        }
    }, [key, defaultValue])

    // state变化时同步到sessionStorage
    useEffect(() => {
        sessionStorage.setItem(key, JSON.stringify(sessionItem))
    }, [key, sessionItem])

    return [sessionItem, setSessionItem]
}

关键改动说明

  1. 统一初始值:将useState的初始值直接设为defaultValue,确保服务端渲染的输入框value和客户端hydration时的初始state一致,从根源解决不匹配问题。
  2. 客户端延迟初始化:通过useEffect在客户端挂载完成后读取sessionStorage并更新state,这个过程在hydration完成后执行,不会影响初始渲染的一致性。
  3. 增加异常处理:给JSON.parse添加捕获逻辑,避免存储值格式错误导致的页面异常。

修改后,页面渲染完成后直接删除输入框全部内容时,onChange会正常触发,state和sessionStorage也会同步更新为空值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 16:30:59