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

useState更新引发useQuery两次调用的技术问题咨询

解决useQuery重复调用的问题

问题根源是组件初始化时filterState的初始值为false,触发第一次查询;随后useEffect从本地存储获取到真实值并更新filterState,导致组件重渲染,触发第二次查询。

方案1:使用useQuery的enabled选项控制查询时机

通过enabled参数让查询仅在拿到真实的filter值后才执行,这是最推荐的方案,既保留useQuery的缓存和自动更新特性,又能避免无效请求:

const DashboardComponent = () => {
  // 初始值设为null,标记filter还未从本地存储加载完成
  const [filterState, setFilter] = useState(null);

  const returnFilteredState = async () => {
    return await localforage.getItem<boolean>('watchedAndReviewedFilterd') || false;
  };

  useEffect(() => {
    returnFilteredState().then((value) => {
      setFilter(value);
    });
  }, []);

  const {error, loading, data: {moviesFromUser: movies} = {}} =
    useQuery(resolvers.queries.ReturnMoviesFromUser, {
      variables: {
        userId: currentUserVar().id,
        // 兜底使用false,避免filterState为null时变量异常
        filter: filterState ?? false,
      },
      // 仅当filterState不为null时,才执行查询
      enabled: filterState !== null,
    });
};

方案2:改用useLazyQuery手动触发查询

先获取到filter值后,再手动调用查询函数,完全掌控查询触发时机:

const DashboardComponent = () => {
  const [filterState, setFilter] = useState(false);
  // 初始化useLazyQuery,拿到手动触发查询的函数
  const [getMovies, {error, loading, data: {moviesFromUser: movies} = {}}] =
    useLazyQuery(resolvers.queries.ReturnMoviesFromUser);

  const returnFilteredState = async () => {
    const value = await localforage.getItem<boolean>('watchedAndReviewedFilterd') || false;
    setFilter(value);
    // 拿到真实filter值后,手动触发查询
    getMovies({
      variables: {
        userId: currentUserVar().id,
        filter: value,
      },
    });
  };

  useEffect(() => {
    returnFilteredState();
  }, []);
};

方案3:同步获取本地存储值(仅适用于非异步存储API)

如果可以替换localforage为同步的localStorage,可以直接在组件初始化时获取filter值,避免异步状态更新触发重渲染:

const DashboardComponent = () => {
  // 同步获取本地存储值,直接作为初始状态
  const filterState = JSON.parse(localStorage.getItem('watchedAndReviewedFilterd') || 'false');

  const {error, loading, data: {moviesFromUser: movies} = {}} =
    useQuery(resolvers.queries.ReturnMoviesFromUser, {
      variables: {
        userId: currentUserVar().id,
        filter: filterState,
      },
    });
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 11:36:16