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

Tanstack onMutate回调中React状态更新无法触发Modal问题

问题分析与解决方案

核心问题

你遇到的问题根源是模态框状态未在组件间共享:每次调用useModal钩子都会创建一套完全独立的isOpen状态和操作函数。useApproval里调用的handleOpenModal修改的是它自己实例的状态,而Modal组件读取的是另一套独立状态,两者完全无关,自然无法触发模态框显示。

解决方案:用React Context实现状态共享

通过创建全局共享的模态框上下文,让所有需要访问模态框状态的组件共用同一套状态实例。

步骤1:重构useModal钩子,添加Context支持

// hooks/useModal.ts
import { createContext, useContext, useCallback, useState, ReactNode } from "react";

// 定义上下文类型
interface ModalContextType {
  isOpen: boolean;
  handleOpenModal: () => void;
  handleCloseModal: () => void;
}

// 创建上下文,默认值为undefined
const ModalContext = createContext<ModalContextType | undefined>(undefined);

// 上下文提供者组件
export function ModalProvider({ children }: { children: ReactNode }) {
  const [isOpen, setIsOpen] = useState(false);
  const handleOpenModal = useCallback(() => setIsOpen(true), []);
  const handleCloseModal = useCallback(() => setIsOpen(false), []);

  return (
    <ModalContext.Provider value={{ isOpen, handleOpenModal, handleCloseModal }}>
      {children}
    </ModalContext.Provider>
  );
}

// 自定义钩子,用于消费上下文
export function useModal() {
  const context = useContext(ModalContext);
  if (!context) {
    throw new Error("useModal必须在ModalProvider组件内部使用");
  }
  return context;
}

步骤2:在父组件中包裹提供者

修改ConnectionOptions组件,用ModalProvider包裹需要共享状态的子组件:

// ConnectionOptions.tsx
import { useState, useCallback } from "react";
import { useTrade } from "@/hooks";
import { ModalProvider } from "@/hooks/useModal";
import Modal from "./Modal";

function ConnectionOptions() {
  const [tokenInAmount, setTokenInAmount] = useState(0);
  const { onTrade } = useTrade();
  
  // 修复闭包问题:添加tokenInAmount到依赖数组
  const handleExecuteTrade = useCallback(() => {
    onTrade(tokenInAmount);
  }, [onTrade, tokenInAmount]);

  return (
    <ModalProvider>
      <Main>
        <Button onClick={handleExecuteTrade}>
          Trade
        </Button>
        <Modal />
      </Main>
    </ModalProvider>
  );
}

步骤3:保持原有组件逻辑不变

useApproval、Modal组件的代码无需修改,它们通过useModal钩子消费的是共享上下文里的状态,现在调用handleOpenModal会直接修改Modal组件读取的isOpen状态,模态框就能正常显示了。

额外修复:闭包问题

原代码中handleExecuteTrade的依赖数组遗漏了tokenInAmount,会导致当输入金额变化时,函数仍然使用旧的金额值,已经在上面的代码中修复。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 00:34:56