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

如何导出useContext变量,无需每个组件调用useContext即可直接导入使用?

解决方案

可以实现你需要的直接导入toast对象的使用方式,具体实现思路和代码如下:

实现思路

我们可以在Toast Provider组件挂载时,把内部可用的toast实例赋值给模块顶层的共享变量,再基于这个变量封装统一的toast对象导出,外部导入后就可以直接调用对应的方法,不需要在每个组件内调用useToast钩子,原有Toast的渲染逻辑完全不需要改动。

完整代码修改示例

// toast-provider.tsx
import { createContext, useContext, ReactNode, useEffect } from 'react';

// 你项目中原有的Toast实例类型,可根据实际需求扩展
type ToastType = {
  success: (message: string) => void;
  error: (message: string) => void;
  info: (message: string) => void;
  warning: (message: string) => void;
}

// 模块顶层的共享toast实例引用
let globalToastRef: ToastType | null = null;

// 导出供外部直接调用的toast对象
export const toast: ToastType = {
  success: (message) => {
    if (!globalToastRef) {
      throw new Error('Toast未初始化,请确认项目根节点已包裹ToastProvider');
    }
    globalToastRef.success(message);
  },
  error: (message) => {
    if (!globalToastRef) {
      throw new Error('Toast未初始化,请确认项目根节点已包裹ToastProvider');
    }
    globalToastRef.error(message);
  },
  info: (message) => {
    if (!globalToastRef) {
      throw new Error('Toast未初始化,请确认项目根节点已包裹ToastProvider');
    }
    globalToastRef.info(message);
  },
  warning: (message) => {
    if (!globalToastRef) {
      throw new Error('Toast未初始化,请确认项目根节点已包裹ToastProvider');
    }
    globalToastRef.warning(message);
  },
};

// 原有Context逻辑保留,不影响旧代码使用useToast
const ToastContext = createContext<ToastType | undefined>(undefined);

export const ToastProvider = ({ children }: { children: ReactNode }) => {
  // 你项目中原有的toast实例实现,包括维护消息队列、渲染弹窗等逻辑,不需要修改
  const toastInstance: ToastType = {
    success: (msg) => { /* 原有成功提示逻辑 */ },
    error: (msg) => { /* 原有错误提示逻辑 */ },
    info: (msg) => { /* 原有信息提示逻辑 */ },
    warning: (msg) => { /* 原有警告提示逻辑 */ },
  };

  // 组件挂载时将实例赋值给全局引用
  useEffect(() => {
    globalToastRef = toastInstance;
    // 卸载时清空引用避免内存泄漏
    return () => {
      globalToastRef = null;
    };
  }, [toastInstance]);

  return (
    <ToastContext.Provider value={toastInstance}>
      {children}
      {/* 原有Toast消息列表的渲染DOM */}
    </ToastContext.Provider>
  );
};

// 原有useToast钩子保留,兼容旧代码
export const useToast = () => {
  const context = useContext(ToastContext);
  if (!context) throw new Error('useToast必须在ToastProvider内部使用');
  return context;
};

注意事项

  • 该方案的使用前提和原有用法一致,必须保证项目根节点已包裹ToastProvider,否则调用toast方法会抛出未初始化错误
  • Toast的渲染表现和原有方案完全一致,不会出现功能差异
  • 若你的项目是服务端渲染(SSR/SSG)场景,服务端运行时不会执行客户端挂载逻辑,直接调用toast会报错,仅可在客户端侧执行的逻辑(如点击事件、useEffect回调)中调用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 04:54:03