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

Next.js 14中使用Zustand Persist页面刷新数值闪烁问题求助

解决Next.js 14中Zustand persist持久化数值的闪烁问题

问题根源

闪烁问题主要来自两个核心原因:

  • 自定义useStore钩子导致状态延迟更新:初始data为undefined,页面先渲染默认值0或空白,等useEffect触发后才更新为持久化存储的数值,造成视觉闪烁。
  • 服务端与客户端Hydration不匹配:服务端渲染时没有localStorage,Zustand只能用初始值0;客户端Hydrate阶段先显示服务端返回的0,随后persist中间件从本地存储加载真实值,导致数值跳变。

解决方案

1. 移除多余的自定义useStore钩子

Zustand原生的useCountStore已经可以直接获取和监听状态变化,这个自定义封装完全没必要,反而会引入状态更新延迟的问题。

2. 消除Hydration数值差异

通过判断客户端环境,确保只有在客户端加载完成后才显示持久化的数值,避免服务端初始值与客户端真实值的冲突。

修改后的代码

app/page.tsx

'use client'
import Button from '@mui/material/Button'
import { useCountStore } from '@/app/store/useCountStore'
import { useEffect, useState } from 'react'

const Home = () => {
  const { num, increaseNum, decreaseNum } = useCountStore()
  // 标记是否已进入客户端环境
  const [isClientReady, setIsClientReady] = useState(false)

  useEffect(() => {
    // 仅在客户端触发,确认环境就绪
    setIsClientReady(true)
  }, [])

  return (
    <>
      {/* 客户端就绪前显示服务端一致的初始值,避免Hydration不匹配 */}
      <div className='text-[red] text-[24px]'>{isClientReady ? num : 0}</div>
      <Button onClick={increaseNum} variant='contained'>increase number</Button>
      <Button onClick={decreaseNum} variant='contained'>decrease number</Button>
    </>
  )
}
export default Home

store/useCountStore.ts(保持原代码即可)

import { create } from 'zustand'
import { persist } from 'zustand/middleware'

interface countType {
    num: number,
    increaseNum: () => void,
    decreaseNum: () => void
}
export const useCountStore = create(persist<countType>((set, get) => ({
    num: 0,
    increaseNum: () => set({ num: get().num + 1 }),
    decreaseNum: () => set({ num: get().num - 1 }),
}), { name: 'count_storage_tag' }))

原理说明

  • 移除自定义useStore后,Zustand会直接响应状态变化,不会出现延迟更新的情况。
  • 通过useEffect标记客户端就绪状态,确保服务端渲染时显示与初始值一致的内容,客户端加载完成后再切换为持久化的真实数值,彻底消除Hydration不匹配导致的闪烁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 11:17:36