react-intl 未找到 v4 升级 `IntlProvider` 阻止组件在使用 `injectIntl` 包装器时显示
react-intl v4 upgrade `IntlProvider` not found preventing component from displaying when using `injectIntl` wrapper
我正在尝试从 react-intl v 2.3.0 升级到 4.5.1。自升级以来,我 运行 遇到了一些围绕 injectIntl
HOC 的问题。我在 monorepo 中有一个共享组件库,它被导入到不同的功能中(在 repo 的单独部分中导入的共享和本地唯一组件的组合)。但是,我的 IntlProvider
存在于我的共享组件库中,我们导入了一个名为 AppShell
的组件,其中包含任何需要的提供程序(包括 intl),它包装了每个功能的顶层。
我听从了关于 formatjs 存储库问题的建议,并从我的共享组件库中删除了 react-intl 版本。这解决了我的大部分问题,但有一些注意事项。
请注意,以下所有示例都使用 react-intl 版本 4.5.1 的功能文件夹,以及未安装 react-intl 版本的共享组件库
修复尝试 1
如果我尝试使用 react-intl
中的 injectIntl
HOC,该组件将不会在页面上呈现,并且出现以下错误:
代码示例(AppShell 包装器组件位于顶层 ReactDOM.render
函数中):
import { FormattedMessage, injectIntl } from 'react-intl';
// shared component library
import { Alert } from '@shared/components/alert';
// component custom to feature, also can contain shared components
import WorkspaceListContainer from './workspaceListContainer';
import messages from './messages';
export class AppLifecycleMenu extends Component {
render() {
const deleteAlertTitle = this.props.intl.formatMessage(
messages.deleteAlertTitle,
{ alertName: name }
);
return (
<Fragment>
<WorkspaceListContainer />
<Alert
title={deleteAlertTitle}
okButtonText={<FormattedMessage {...messages.deleteOkButton} />}
cancelButtonText={<FormattedMessage {...messages.deleteCancelButton} />}
/>
</Fragment>
);
}
}
export default injectIntl(AppLifecycleMenu);
请注意,在我们的许多共享组件中,intl
消息可以作为 props 传递,并且一些组件包装在它们自己的 injectIntl
HOC 到 props 的国际默认版本(例如默认按钮标签)。
修复尝试 2
但是,如果我导入共享资源库中的 injectIntl
帮助程序,组件会呈现但仍会显示错误消息:
injectIntlHelper 代码:
// only apply intl in non-test environments
export default Component => process.env.NODE_ENV === TEST_ENV ? Component : injectIntl(Component);
代码示例(AppShell 包装器组件位于顶层 ReactDOM.render
函数中):
import { FormattedMessage, injectIntl } from 'react-intl';
// shared component library
import { Alert } from '@shared/components/alert';
import injectIntl from '@shared/utilities/injectIntl';
// component custom to feature, also can contain shared components
import WorkspaceListContainer from './workspaceListContainer';
import messages from './messages';
export class DeleteWorkspaceAlert extends Component {
render() {
const deleteAlertTitle = this.props.intl.formatMessage(
messages.deleteAlertTitle,
{ alertName: name }
);
return (
<Fragment>
<WorkspaceListContainer />
<Alert
title={deleteAlertTitle}
okButtonText={<FormattedMessage {...messages.deleteOkButton} />}
cancelButtonText={<FormattedMessage {...messages.deleteCancelButton} />}
/>
</Fragment>
);
}
}
export default injectIntl(AppLifecycleMenu);
具有 intlprovider 的组件树:
错误信息:
修复尝试 3
我也试过只在共享资源库中安装 react-intl
但这导致了这个错误消息:
环境
我曾尝试降低 react-intl 中的版本,但这个问题一直存在到 3.0 及更高版本中
我已经尝试了不同的组合并在网上查找了几天,我可以做任何其他更改来消除这些错误吗?有没有什么是我遗漏了在版本之间添加或更新的东西?
对于遇到此问题的任何人,我的问题已通过 following/modifying 问题的修复解决:https://github.com/formatjs/formatjs/issues/1620
与上面链接的问题不同,我的项目 IntlProvider
存在于共享资源库中并被导出以包装组件。因此,我从共享资源库以外的所有文件夹中删除了 react-intl
依赖项,并从那里导出了任何需要的组件。
所以我在非共享组件文件夹中的导入看起来像
import injectIntl, { FormattedMessage, FormattedDate } from '@shared/utils/intl';
我的共享库中的组件具有如下所示的文件
import { FormattedMessage } from 'react-intl;
export FormattedMessage;
本期相关引述:
I think the reason [having multiple dependencies] worked with older version is old React context API. New React context API rely on same reference. You project instantiates react context from different node_modules thus contexts are not same reference. This also means you are bundling react-intl twice in your application.
我正在尝试从 react-intl v 2.3.0 升级到 4.5.1。自升级以来,我 运行 遇到了一些围绕 injectIntl
HOC 的问题。我在 monorepo 中有一个共享组件库,它被导入到不同的功能中(在 repo 的单独部分中导入的共享和本地唯一组件的组合)。但是,我的 IntlProvider
存在于我的共享组件库中,我们导入了一个名为 AppShell
的组件,其中包含任何需要的提供程序(包括 intl),它包装了每个功能的顶层。
我听从了关于 formatjs 存储库问题的建议,并从我的共享组件库中删除了 react-intl 版本。这解决了我的大部分问题,但有一些注意事项。
请注意,以下所有示例都使用 react-intl 版本 4.5.1 的功能文件夹,以及未安装 react-intl 版本的共享组件库
修复尝试 1
如果我尝试使用 react-intl
中的 injectIntl
HOC,该组件将不会在页面上呈现,并且出现以下错误:
代码示例(AppShell 包装器组件位于顶层 ReactDOM.render
函数中):
import { FormattedMessage, injectIntl } from 'react-intl';
// shared component library
import { Alert } from '@shared/components/alert';
// component custom to feature, also can contain shared components
import WorkspaceListContainer from './workspaceListContainer';
import messages from './messages';
export class AppLifecycleMenu extends Component {
render() {
const deleteAlertTitle = this.props.intl.formatMessage(
messages.deleteAlertTitle,
{ alertName: name }
);
return (
<Fragment>
<WorkspaceListContainer />
<Alert
title={deleteAlertTitle}
okButtonText={<FormattedMessage {...messages.deleteOkButton} />}
cancelButtonText={<FormattedMessage {...messages.deleteCancelButton} />}
/>
</Fragment>
);
}
}
export default injectIntl(AppLifecycleMenu);
请注意,在我们的许多共享组件中,intl
消息可以作为 props 传递,并且一些组件包装在它们自己的 injectIntl
HOC 到 props 的国际默认版本(例如默认按钮标签)。
修复尝试 2
但是,如果我导入共享资源库中的 injectIntl
帮助程序,组件会呈现但仍会显示错误消息:
injectIntlHelper 代码:
// only apply intl in non-test environments
export default Component => process.env.NODE_ENV === TEST_ENV ? Component : injectIntl(Component);
代码示例(AppShell 包装器组件位于顶层 ReactDOM.render
函数中):
import { FormattedMessage, injectIntl } from 'react-intl';
// shared component library
import { Alert } from '@shared/components/alert';
import injectIntl from '@shared/utilities/injectIntl';
// component custom to feature, also can contain shared components
import WorkspaceListContainer from './workspaceListContainer';
import messages from './messages';
export class DeleteWorkspaceAlert extends Component {
render() {
const deleteAlertTitle = this.props.intl.formatMessage(
messages.deleteAlertTitle,
{ alertName: name }
);
return (
<Fragment>
<WorkspaceListContainer />
<Alert
title={deleteAlertTitle}
okButtonText={<FormattedMessage {...messages.deleteOkButton} />}
cancelButtonText={<FormattedMessage {...messages.deleteCancelButton} />}
/>
</Fragment>
);
}
}
export default injectIntl(AppLifecycleMenu);
具有 intlprovider 的组件树:
错误信息:
修复尝试 3
我也试过只在共享资源库中安装 react-intl
但这导致了这个错误消息:
环境
我曾尝试降低 react-intl 中的版本,但这个问题一直存在到 3.0 及更高版本中
我已经尝试了不同的组合并在网上查找了几天,我可以做任何其他更改来消除这些错误吗?有没有什么是我遗漏了在版本之间添加或更新的东西?
对于遇到此问题的任何人,我的问题已通过 following/modifying 问题的修复解决:https://github.com/formatjs/formatjs/issues/1620
与上面链接的问题不同,我的项目 IntlProvider
存在于共享资源库中并被导出以包装组件。因此,我从共享资源库以外的所有文件夹中删除了 react-intl
依赖项,并从那里导出了任何需要的组件。
所以我在非共享组件文件夹中的导入看起来像
import injectIntl, { FormattedMessage, FormattedDate } from '@shared/utils/intl';
我的共享库中的组件具有如下所示的文件
import { FormattedMessage } from 'react-intl;
export FormattedMessage;
本期相关引述:
I think the reason [having multiple dependencies] worked with older version is old React context API. New React context API rely on same reference. You project instantiates react context from different node_modules thus contexts are not same reference. This also means you are bundling react-intl twice in your application.