在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
相关产品推荐
相关产品推荐

