React 前端导航

antd Modal.configm 中使用 FormattedMessage 报错:Uncaught Error: [React Intl] Could not find required `intl` object. <IntlProvider> needs to exist in the component ancestry.

antd Modal.configm 中使用 FormattedMessage 报错:Uncaught Error: [React Intl] Could not find required 'intl' object. needs to exist in the component ancestry.

问题复现

在 Modal.confirm 中使用FormattedMessage,示例代码如下:

<Button
    onClick={() => {
        Modal.confirm({
        title: <FormattedMessage id="operation.confirm" />,
        onOk: async () => {
            await delCtrlData(item.id);
        },
        });
    }}
    type="link"
    danger
    >
    <DeleteOutlined />
    <FormattedMessage id="operation.delete" />
</Button>

错误提示如下:

Uncaught Error: [React Intl] Could not find required `intl` object. <IntlProvider> needs to exist in the component ancestry.
    at invariant (mf-dep_vendors-node_modules_react-intl_lib_index_js.37b86786.async.js:17:15)
    at invariantIntlContext (mf-dep_vendors-node_modules_react-intl_lib_index_js.37b86786.async.js:1951:66)
    at mf-dep_vendors-node_modules_react-intl_lib_index_js.37b86786.async.js:816:71
    at updateContextConsumer (mf-dep_vendors-node_modules_react-dom_index_js.befe9138.async.js:18756:19)
    at beginWork (mf-dep_vendors-node_modules_react-dom_index_js.befe9138.async.js:19123:14)
    at HTMLUnknownElement.callCallback (mf-dep_vendors-node_modules_react-dom_index_js.befe9138.async.js:3954:14)
    at Object.invokeGuardedCallbackDev (mf-dep_vendors-node_modules_react-dom_index_js.befe9138.async.js:4003:16)
    at invokeGuardedCallback (mf-dep_vendors-node_modules_react-dom_index_js.befe9138.async.js:4065:31)
    at beginWork$1 (mf-dep_vendors-node_modules_react-dom_index_js.befe9138.async.js:23968:7)
    at performUnitOfWork (mf-dep_vendors-node_modules_react-dom_index_js.befe9138.async.js:22780:12)
    at workLoopSync (mf-dep_vendors-node_modules_react-dom_index_js.befe9138.async.js:22711:5)
    at renderRootSync (mf-dep_vendors-node_modules_react-dom_index_js.befe9138.async.js:22674:7)
    at performSyncWorkOnRoot (mf-dep_vendors-node_modules_react-dom_index_js.befe9138.async.js:22297:18)
    at scheduleUpdateOnFiber (mf-dep_vendors-node_modules_react-dom_index_js.befe9138.async.js:21885:7)
    at updateContainer (mf-dep_vendors-node_modules_react-dom_index_js.befe9138.async.js:25486:3)
    at mf-dep_vendors-node_modules_react-dom_index_js.befe9138.async.js:26025:7
    at unbatchedUpdates (mf-dep_vendors-node_modules_react-dom_index_js.befe9138.async.js:22435:12)
    at legacyRenderSubtreeIntoContainer (mf-dep_vendors-node_modules_react-dom_index_js.befe9138.async.js:26024:5)
    at Object.render (mf-dep_vendors-node_modules_react-dom_index_js.befe9138.async.js:26107:10)
    at mf-dep_vendors-node_modules_antd_es_modal_index_js.c9cbf0ad.async.js:558:46

问题原因

Modal.confirm 是在被调用运行时 使用 ReactDom.render 执行的 Modal 组件渲染,相当于新创建了一个 React 应用,外部 Context 在渲染时已经丢失,所以无法访问到 intl 提供的 FormatMessage 组件。

Modal.confirm 方法的 render 源码如下:

 function render({ okText, cancelText, prefixCls: customizePrefixCls, ...props }: any) {
    /**
     * https://github.com/ant-design/ant-design/issues/23623
     *
     * Sync render blocks React event. Let's make this async.
     */
    setTimeout(() => {
      const runtimeLocale = getConfirmLocale();
      const { getPrefixCls, getIconPrefixCls } = globalConfig();
      // because Modal.config  set rootPrefixCls, which is different from other components
      const rootPrefixCls = getPrefixCls(undefined, getRootPrefixCls());
      const prefixCls = customizePrefixCls || `${rootPrefixCls}-modal`;
      const iconPrefixCls = getIconPrefixCls();

      ReactDOM.render(
        <ConfirmDialog
          {...props}
          prefixCls={prefixCls}
          rootPrefixCls={rootPrefixCls}
          iconPrefixCls={iconPrefixCls}
          okText={okText || (props.okCancel ? runtimeLocale.okText : runtimeLocale.justOkText)}
          cancelText={cancelText || runtimeLocale.cancelText}
        />,
        container,
      );
    });

如何解决

第一种也是相对简单的方式是将 FormattedMessage 组件替换为 intl.formatMessage({id:"message.id"}),这样在外部组件渲染时 API 调用已经执行完成,就不会报错了。

第二种是重新封装一下 Modeal.confirm 方法,使用 react-intl 提供的 injectIntl 方法包一层,将 intl 注入到你组件内部方可使用。

声明:本网站发布的内容(图片、视频和文字)以原创、转载和分享网络内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。邮箱:farmerlzj@163.com。 本站原创内容未经允许不得转载,或转载时需注明出处: 内容转载自: React前端网:https://qianduan.shop/blogs/detail/43

#react#antd#Modal#FormattedMessage

相关推荐

react中实现markdown文件读取展示

react中实现markdown文件读取展示

umi实践问题汇总--持续更新

在使用umi的过程中所遇到问题的记录汇总