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

在onChange事件中更新Zustand Store引发输入延迟的解决方案

仅使用Zustand解决Autocomplete输入卡顿问题

问题原因

你当前的实现中,输入框每输入一个字符就会调用setSearch更新Zustand状态,进而触发useGetArticlesBySearch里的异步请求。频繁的状态更新和网络请求会导致组件频繁重渲染,最终引发输入延迟卡顿。

纯Zustand解决方案

以下是两种仅依赖Zustand的优化方案,核心思路是减少不必要的状态更新和请求触发频率:


方案1:在Zustand Store中实现防抖的搜索状态更新

直接在Store层对setSearch做防抖处理,避免每次输入都立即更新状态和发起请求。

// 你的Zustand Store文件
import { create } from 'zustand';
// 也可以自己实现简单防抖,无需依赖lodash
import { debounce } from 'lodash';

interface DirectlyPurchaseRequestOrderStore {
  search: string;
  setSearch: (value: string) => void;
  // 其他状态和方法...
}

export const useDirectlyPurchaseRequestOrderStore = create<DirectlyPurchaseRequestOrderStore>((set) => ({
  search: '',
  // 防抖300ms,可根据需求调整时长
  setSearch: debounce((value: string) => {
    set({ search: value });
  }, 300),
}));

组件中使用方式不变:

<TextField
  {...params}
  onChange={(e) => {
    setSearch(e.target.value);
  }}
/>

方案2:将异步请求逻辑整合到Zustand Store中

把请求、loading状态、文章数据都托管到Store内部,同时对搜索请求做防抖,进一步简化组件逻辑,减少组件层面的重渲染触发。

// 优化后的Zustand Store
import { create } from 'zustand';
import { debounce } from 'lodash';
import type { Article } from './your-types';

interface DirectlyPurchaseRequestOrderStore {
  search: string;
  articles: Article[];
  isLoadingArticles: boolean;
  setSearch: (value: string) => void;
  fetchArticlesBySearch: (search: string) => Promise<void>;
}

export const useDirectlyPurchaseRequestOrderStore = create<DirectlyPurchaseRequestOrderStore>((set) => ({
  search: '',
  articles: [],
  isLoadingArticles: false,
  setSearch: debounce((value: string) => {
    set({ search: value });
    // 直接在防抖的setSearch里触发请求
    useDirectlyPurchaseRequestOrderStore.getState().fetchArticlesBySearch(value);
  }, 300),
  fetchArticlesBySearch: async (search) => {
    if (!search.trim()) {
      set({ articles: [], isLoadingArticles: false });
      return;
    }
    set({ isLoadingArticles: true });
    try {
      const res = await getArticlesBySearch(search);
      set({ articles: res });
    } catch (error) {
      console.error(error);
      set({ articles: [] });
    } finally {
      set({ isLoadingArticles: false });
    }
  },
}));

组件中使用时直接从Store获取数据:

const BuildOrder = (props: { setOpen: Function }) => {
  const { setSearch, articles, isLoadingArticles } = useDirectlyPurchaseRequestOrderStore(
    useShallow((state) => ({
      setSearch: state.setSearch,
      articles: state.articles,
      isLoadingArticles: state.isLoadingArticles,
    }))
  );

  return (
    <Autocomplete
      // 配置项...
      options={articles}
      loading={isLoadingArticles}
      renderInput={(params) => (
        <TextField
          {...params}
          onChange={(e) => {
            setSearch(e.target.value);
          }}
        />
      )}
    />
  );
};

方案优势

  • 防抖处理从根源上减少了请求次数,避免频繁的网络请求和状态更新
  • 将请求逻辑整合到Store后,组件无需再维护useState和useEffect,代码更简洁
  • 利用Zustand的状态管理,确保数据在多个组件间共享时的一致性

内容的提问来源于stack exchange,提问作者Jesus Tadeo Osuna Luna

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 05:00:20