【问题标题】:Can't use props when passing { t } (from i18n-react) to stateless component将 { t }(来自 i18n-react)传递给无状态组件时不能使用道具
【发布时间】:2019-05-12 11:30:07
【问题描述】:

我有具有状态的父组件:

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

它尝试渲染它的孩子并将道具传递给它:

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

ChangeHistory 组件尝试映射接收到的道具以呈现元素列表:

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 属性未定义。但是如果在inspector中点击一下,就可以看到值已经传递成功了:

我不明白这个问题。可能是因为我使用 i18n 并使用 withNamespaces 对道具做了一些事情还是......?我必须知道如何解决这个问题。

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

编辑:我尝试删除 { t } 方法并从导出中删除 withNamesSpaces() HOC,现在一切正常。但是现在我不能在这个组件中使用i18n-react :(

【问题讨论】:

  • 签名中的{ t }是什么?你在解构参数吗?
  • @Meir { t } 来自 i18n-react,我用它来将界面翻译成英文并返回。我尝试将其完全删除,但没有帮助。
  • 你为什么不直接导入它然后引用它呢? import justPickAnyName from 'package-name'; 然后像这样使用它:justPickAnyName.t('message key');
  • @Amsvartner 是的,我已经做到了,请在下面查看我的答案。我不知道我能做到这一点,第一次使用 i18n,有点看懂了“操作方法”文章。

标签: javascript reactjs ecmascript-6 internationalization i18next


【解决方案1】:

我认为问题出在组件参数上:

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

应该是:

const ChangeHistoryCard = (props) => ();

【讨论】:

    【解决方案2】:

    所以,如果您阅读第二次编辑,您就会知道,如果我从组件中完全删除 i18n,一切似乎都可以正常工作。

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

    您可以将import 'i18next' 并调用t 作为其方法,而不是将{ 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);
    

    Thay way i18n 保持原状,而道具保持不变且可用。

    【讨论】:

      【解决方案3】:

      功能组件的签名只获取props

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

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

      改变

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

      const ChangeHistoryCard = (props) => ();
      

      【讨论】:

        猜你喜欢
        • 2016-10-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-19
        • 2020-12-21
        • 2017-04-30
        • 2020-10-08
        • 2019-09-18
        相关资源
        最近更新 更多