首页 > 解决方案 > 找不到所需的“intl”对象。需要存在于组件祖先中

问题描述

在使用 React Intl 进行本地化时,我们不断通过 Airbreak 从我们的 React 应用程序中收到随机错误消息。

错误信息

不变违规:[React Intl] 找不到所需intl的对象。需要存在于组件祖先中。

我们的应用程序非常小。我们有三个页面,其中一个页面嵌入了多个模式对话框,然后可能由用户打开。我们无法将此问题精确定位到确切的浏览器、版本或代码点。

我们试图深入研究错误消息并找到确切原因,但没有运气。模态对话框作为主组件的子组件存在,并在渲染父组件时嵌入。

我们的 main.js 渲染是这样用 IntlProvider 包装的:

render() {
    return (
        <ErrorBoundary>
            <IntlProvider locale={language} messages={messages[language]}>
                <Router> 
                    <Route render={({location}) => (
                        <div id="site-container">
                                     ...

ErrorBoundary 是 Airbrake。IntlProvider 获取语言环境和翻译的字符串。

父组件已注入 Intl:

Page.propTypes = {
intl: intlShape.isRequired
};

export default injectIntl(Page);

IntlProvider 的用法与文档描述的一样,应该使用,但是我们在这里遗漏了什么吗?这个错误的原因是什么?某些对话框没有获得为它提供的 intl?

我们不应该得到这些错误。如果确实如此,它似乎会导致任何页面加载完全崩溃。

标签: reactjsintl

解决方案


为我解决此问题的解决方案是确保每次需要在开玩笑测试中安装组件时都使用 i18n 安装测试文件。这是一个例子:

it('set the value to 4 if changed value is not a number', () => {
  const wrapper = mountWithTestFileI18N(<Component {...props} />);
  wrapper.find('.form-input').simulate('change', { target: { value: 'tt' } });
  wrapper.find('.form-input').simulate('blur');

  expect(wrapper.find('.form-input').props().value).toBe(4);
});

您需要确保在每次开玩笑测试时都遵循这个安装公式。你应该在你的 jestsetup.js 文件中有你的挂载函数。这是一个例子:

function mountWithIntl(node, intlKeys, formatKeys, { context, childContextTypes } = 
    {}) {
  const { intl } = getIntlContext(intlKeys, formatKeys);
  return mount(nodeWithIntlProp(node, intl), {
    context: { ...context, intl },
    childContextTypes: { ...childContextTypes, intl: intlShape },
  });
}

推荐阅读