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

使用Zustand导致React渲染循环问题求助

解决Zustand结合Immer时的Maximum update depth exceeded错误

问题原因

你调用useResidentialStore时传入的选择器函数,每次都会返回一个全新的对象。Zustand默认通过引用比较判断状态是否变化,由于每次返回的对象引用不同,Zustand会误判状态更新,触发组件重渲染;重渲染时选择器又返回新对象,如此循环就导致了更新深度超限的错误。而单独获取单个值时,返回的是原始类型或稳定引用的对象,浅比较能识别出状态未变化,所以不会触发循环。

解决方案

1. 使用shallow比较器(推荐)

Zustand提供的shallow工具,可让选择器返回的对象通过浅比较判断变化,而非直接比较对象引用。

首先导入shallow:

import { create, shallow } from "zustand"

然后在使用store时传入shallow作为第二个参数:

const {
  minPrice,
  minPriceOptions,
  setMinPrice,
} = useResidentialStore(state => ({
  minPrice: state.minPrice,
  minPriceOptions: state.minPriceOptions,
  setMinPrice: state.setMinPrice,
}), shallow)

2. 拆分多个useResidentialStore调用

既然单独取单个值无问题,可将解构拆分为多个独立调用:

const minPrice = useResidentialStore(state => state.minPrice)
const minPriceOptions = useResidentialStore(state => state.minPriceOptions)
const setMinPrice = useResidentialStore(state => state.setMinPrice)

3. 用useMemo缓存选择器(可选)

通过useMemo让选择器的引用保持稳定,避免每次渲染生成新函数:

import { useMemo } from "react"

// 组件内
const selectResidentialData = useMemo(() => state => ({
  minPrice: state.minPrice,
  minPriceOptions: state.minPriceOptions,
  setMinPrice: state.setMinPrice,
}), [])

const {
  minPrice,
  minPriceOptions,
  setMinPrice,
} = useResidentialStore(selectResidentialData)

此方式不如shallow简洁,一般优先选择第一种方案。

验证修改效果

采用第一种方案的完整组件内代码示例:

import { useResidentialStore } from "../path-to-your-store-file"
import { shallow } from "zustand"

function YourComponent() {
  const {
    minPrice,
    minPriceOptions,
    setMinPrice,
  } = useResidentialStore(state => ({
    minPrice: state.minPrice,
    minPriceOptions: state.minPriceOptions,
    setMinPrice: state.setMinPrice,
  }), shallow)

  // 组件逻辑...
  return <div>...</div>
}

这样就能避免无意义的渲染循环,Zustand会通过浅比较准确判断状态是否真的更新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 13:52:55