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

React useContext异常:confirmClear不是函数的问题解决

如何正确设置confirmClear函数?

我有一个React应用,需要实现可复用的确认对话框。其中的历史面板组件展示历史列表,并带有“清除历史”按钮,点击该按钮时我希望弹出确认对话框,但此时出现以下错误:

Uncaught (in promise) TypeError: confirmClear is not a function
    _callee$ HistoryPanel.js:18
    Babel 2
    node_modules main.js:133
    Babel 2
    node_modules main.js:35708
    node_modules main.js:35697
    handleClear HistoryPanel.js:17
    React 14
    unstable_runWithPriority scheduler.development.js:468
    React 15
    js index.js:6
    Webpack 3

相关代码

HistoryPanel.js

import React from 'react'
import { useHistory, useHistoryDispatch } from './HistoryProvider'
import useConfirmDialog from "./ConfirmDialog"


export default function HistoryPanel({formatting}) {
  const history = useHistory()
  const historyDispatcher = useHistoryDispatch()
  const confirmClear = useConfirmDialog()

  function display(entry) {
    return( <li key={entry.id}>
              <time dateTime={entry.id}>{new Intl.DateTimeFormat(formatting.locale, formatting.dateFormat).format(entry.id)}</time> {entry.entry}
            </li> )
  }

  const handleClear = async () => {
    const ans = await confirmClear()
    if( ans ) { historyDispatcher({type: "clear"})}
  }
  
  function sorter(a,b) {
    return a.id - b.id
  }
  
  return(
    <section id="history">
      <h1>History</h1>
      <button onClick={handleClear}>Clear History</button>
      <ul className="history">
        { history.sort(sorter).map(display) }
      </ul>
    </section>
  )
}

ConfirmationDialog.js

import React, {
  createContext,
  useCallback,
  useContext,
  useRef,
  useState,
} from 'react';
import Alert from "./Alert"


const ConfirmDialog = createContext();


export function ConfirmDialogProvider({ children }) {
  const [state, setState] = useState({ isOpen: false });
  const fn = useRef();

  const confirm = useCallback(
    (data) => {
      return new Promise((resolve) => {
        setState({ ...data, isOpen: true });
        fn.current = (choice) => {
          resolve(choice);
          setState({ isOpen: false });
        };
      });
    },
    [setState]
  );

  return (
    <ConfirmDialog.Provider value={confirm}>
      {children}
      <Alert
        {...state}
        onClose={() => fn.current(false)}
        onConfirm={() => fn.current(true)}
      />
    </ConfirmDialog.Provider>
  );
}


export default function useConfirmDialog() {
  return useContext(ConfirmDialog);
}

问题分析与解决方案

核心问题

confirmClear is not a function错误的本质是**useConfirmDialog钩子未获取到有效函数**,原因是HistoryPanel组件不在ConfirmDialogProvider的上下文覆盖范围内。

解决步骤

  1. 在顶层组件包裹ConfirmDialogProvider
    必须在应用的顶层(如index.js或App.js)使用ConfirmDialogProvider包裹所有需要调用确认对话框的组件,示例代码:

    // index.js
    import React from 'react';
    import ReactDOM from 'react-dom/client';
    import App from './App';
    import { ConfirmDialogProvider } from './ConfirmationDialog';
    
    const root = ReactDOM.createRoot(document.getElementById('root'));
    root.render(
      <React.StrictMode>
        <ConfirmDialogProvider>
          <App />
        </ConfirmDialogProvider>
      </React.StrictMode>
    );
    
  2. 确认组件层级关系
    确保HistoryPanel是ConfirmDialogProvider的后代组件,只有这样useContext(ConfirmDialog)才能拿到Provider提供的confirm函数。

  3. 补充对话框参数(可选优化)
    从ConfirmationDialog.js的代码来看,confirm函数支持传入data参数传递对话框的标题、内容等信息,可让提示更清晰:

    const handleClear = async () => {
      const ans = await confirmClear({
        title: "确认清除历史",
        message: "确定要清空所有历史记录吗?此操作不可恢复。"
      });
      if( ans ) { historyDispatcher({type: "clear"})}
    }
    

    此步骤需确保Alert组件能接收并渲染这些属性。

验证

完成上述操作后,点击“清除历史”按钮时,confirmClear会正确返回Promise,对话框弹出后用户的选择会被正确解析,进而执行对应的清除操作。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 10:25:56