将{t}(从i18n-react)传递到无状态组件时,不能使用props

时间:2018-12-11 13:00:32

标签: javascript reactjs ecmascript-6 internationalization i18next

我的父组件的状态为:

class RecordEdit extends PureComponent {
    state = { 
        allRecordData: {},
        changelog: [
            {hello1: '1'},
            {hello2: '2'}
        ]
    }

它尝试渲染其子代并将道具传递给它:

<div className='cards-container'>
    <ChangeHistory recordEditHistory={this.state.changelog} />
</div>

ChangeHistory组件尝试在接收到的prop上映射以呈现元素列表:

const ChangeHistoryCard = ({ t }, props) => (
  <CardOuterContainer recordEditHistory={props.recordEditHistory}>
    <h1>{t('История изменений')}</h1>
    {
      props.recordEditHistory &&
      props.recordEditHistory.map(item =>
        <p>{t('Последнее изменение')}: <span>[22.11.2018]</span></p>
      )
    }
  </CardOuterContainer>
);
export default withNamespaces()(ChangeHistoryCard);

由于某种原因,组件始终认为recordEditHistory道具未定义。但是,如果在检查器中单击它,我可以看到该值已成功传递:

Props of ChangeHistoryCard

我不明白问题所在。可能是因为我使用 i18n 并使用withNamespaces对道具或...有所帮助吗?我必须想办法解决这个问题。

重要提示: {t}来自i18n-react,我用它来将界面翻译成英文然后再翻译回来。我尝试将其完全删除,但没有帮助。

编辑:我尝试从导出中删除{ t }方法并删除withNamesSpaces() HOC,现在所有方法都可以使用。但是现在我无法在此组件中使用i18n-react:(

3 个答案:

答案 0 :(得分:1)

我认为问题在于组件参数:

const ChangeHistoryCard = ({ t }, props) => ();

应该是:

const ChangeHistoryCard = (props) => ();

答案 1 :(得分:1)

功能组件的签名仅获得道具

  

https://reactjs.org/docs/components-and-props.html

     

从概念上讲,组件就像JavaScript函数一样。它们接受任意输入(称为“道具”)并返回描述应该在屏幕上显示的内容的React元素。

更改

const ChangeHistoryCard = ({ t }, props) => ();

const ChangeHistoryCard = (props) => ();

答案 2 :(得分:0)

因此,如果您阅读了第二篇文章,您会知道,如果我从组件中完全删除i18n,一切似乎都可以正常工作。

那太好了,但是我真的想留下i18n,所以我找到了一个更好的方法:

您可以{ t }并调用import 'i18next'来代替向组件传递t

所以:

import { withNamespaces } from 'react-i18next';

const ChangeHistoryCard = ({ t }, props) => (
  <CardOuterContainer recordEditHistory={props.recordEditHistory}>
    <h1>{t('История изменений')}</h1>
    {
      props.recordEditHistory &&
      props.recordEditHistory.map(item =>
        <p>{t('Последнее изменение')}: <span>[22.11.2018]</span></p>
      )
    }
  </CardOuterContainer>
);
export default withNamespaces()(ChangeHistoryCard);

成为这个:

import { withNamespaces } from 'react-i18next';
import i18next from 'i18next';

const ChangeHistoryCard = (props) => (
  <CardOuterContainer recordEditHistory={props.recordEditHistory}>
    <h1>{i18next.t('История изменений')}</h1>
    {
      props.recordEditHistory &&
      props.recordEditHistory.map(item =>
        <p>{i18next.t('Последнее изменение')}: <span>[22.11.2018]</span></p>
      )
    }
  </CardOuterContainer>
);


export default withNamespaces()(ChangeHistoryCard);

泰勒方式i18n保持原状,而道具则保持不变且可用。