如何在 React 应用程序中迭代 i18n 对象数组?

发布于 2025-01-13 18:34:36 字数 875 浏览 3 评论 0原文

我在 React 应用程序中使用 i18n 包来翻译一些文本。但我无法迭代作为我的翻译数据的对象数组。

我想迭代 socials 数组并将其显示在我的模板中。但是当我这样做时,它说:socials.map不是一个函数

这是我的翻译json文件:

{
  "socials": [
  {
    "name": "Github",
    "url": "#"
  },
  {
    "name": "Twitter",
    "url": "#"
  },
  {
    "name": "Linkedin",
    "url": "#"
  },
  {
    "name": "Instagram",
    "url": "#"
  }
 ]
}

这是我的jsx代码:

import { useTranslation } from 'react-i18next';

const Content = () => {
  const { t, i18n } = useTranslation();

  const socials = t('socials', { returnObjects: true });

  rerurn (
    <div className="flex">
      {socials.map((social) => (
        <a href={social.url}>{social.name}</a>
      ))}
    </div>
  );
}

export default Content;

我该如何解决这个问题?

I use i18n package in my React application to translate some texts. But I can't iterate through an array of objects which is my translation data.

I want to do iterating through socials array and show it in my template. but when I do that, it says: socials.map is not a function

this is my translation json file:

{
  "socials": [
  {
    "name": "Github",
    "url": "#"
  },
  {
    "name": "Twitter",
    "url": "#"
  },
  {
    "name": "Linkedin",
    "url": "#"
  },
  {
    "name": "Instagram",
    "url": "#"
  }
 ]
}

this is my jsx code:

import { useTranslation } from 'react-i18next';

const Content = () => {
  const { t, i18n } = useTranslation();

  const socials = t('socials', { returnObjects: true });

  rerurn (
    <div className="flex">
      {socials.map((social) => (
        <a href={social.url}>{social.name}</a>
      ))}
    </div>
  );
}

export default Content;

How can I solve this problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

丶情人眼里出诗心の 2025-01-20 18:34:36

您的翻译可能是延迟加载的,并且您可能也没有使用 Suspense。这意味着翻译尚未准备好进行第一次渲染,您需要检查就绪标志: https://react.i18next.com/latest/usetranslation-hook#not-using-suspense

import { useTranslation } from "react-i18next";

const Content = () => {
    const { t, i18n, ready } = useTranslation();

    if (!ready) return "loading translations...";

    const socials = t("socials", { returnObjects: true });

    return (
        <div className="flex">
            {socials.map((social) => (
                <a href={social.url}>{social.name}</a>
            ))}
        </div>
    );
};

export default Content;

Your translations are probably lazy loaded, and you're probably also not using Suspense. This means the translations are not ready for the first render, and you need to check the ready flag: https://react.i18next.com/latest/usetranslation-hook#not-using-suspense

import { useTranslation } from "react-i18next";

const Content = () => {
    const { t, i18n, ready } = useTranslation();

    if (!ready) return "loading translations...";

    const socials = t("socials", { returnObjects: true });

    return (
        <div className="flex">
            {socials.map((social) => (
                <a href={social.url}>{social.name}</a>
            ))}
        </div>
    );
};

export default Content;
心凉怎暖 2025-01-20 18:34:36

在我的例子中,迭代翻译数组效果很好,直到触发了changeLanguage方法。事情是由于某种原因 i18n 将数组项转换为对象的属性。按照上面 Mehdi 的数据:

This:

    {
  "socials": [
  {
    "name": "Github",
    "url": "#"
  },
  {
    "name": "Twitter",
    "url": "#"
  },
  {
    "name": "Linkedin",
    "url": "#"
  },
  {
    "name": "Instagram",
    "url": "#"
  }
 ]
}

变成了 this:

    {
  "socials": {
  social1: {
    "name": "Github",
    "url": "#"
  },
  social2: {
    "name": "Twitter",
    "url": "#"
  },
  social3: {
    "name": "Linkedin",
    "url": "#"
  },
  social4: {
    "name": "Instagram",
    "url": "#"
  }
 }
}

为了使其工作,我编写了一个辅助函数来检查传递的对象是数组还是对象(因为当 18n 被 init()ialized 时,它是一个数组)并且如果它是一个对象,它将其 props 转换回数组项。在此转换映射/循环工作之后,不再出现“.map() 不是函数”错误。

const objToArr = (obj) => {
    if (obj.length > 0) {
      return obj;
    }
    let arr = [];
    for (let i = 0; i < Object.keys(obj).length; i++) {
      const n = `social${i + 1}`;
      arr.push(obj[n]);
    }
    return arr;
  };

返回对象为:

 return (
    <div className="flex">
      {objToArr(socials).map((social) => (
        <a href={social.url}>{social.name}</a>
      ))}
    </div>
  );
}

In my case iterating through translation array worked well until changeLanguage method was triggered. Thing was that for some reason i18n converted array items into properties of an object. Following Mehdi's data from above:

This:

    {
  "socials": [
  {
    "name": "Github",
    "url": "#"
  },
  {
    "name": "Twitter",
    "url": "#"
  },
  {
    "name": "Linkedin",
    "url": "#"
  },
  {
    "name": "Instagram",
    "url": "#"
  }
 ]
}

was turned into this:

    {
  "socials": {
  social1: {
    "name": "Github",
    "url": "#"
  },
  social2: {
    "name": "Twitter",
    "url": "#"
  },
  social3: {
    "name": "Linkedin",
    "url": "#"
  },
  social4: {
    "name": "Instagram",
    "url": "#"
  }
 }
}

To make it work I've written a helper function that checks if passed object is an array or an object (because when 18n is init()ialized, it's an array) and if it's an object it converts its props back into array items. After this conversion mapping / looping works, no more ".map() is not a function" errors.

const objToArr = (obj) => {
    if (obj.length > 0) {
      return obj;
    }
    let arr = [];
    for (let i = 0; i < Object.keys(obj).length; i++) {
      const n = `social${i + 1}`;
      arr.push(obj[n]);
    }
    return arr;
  };

with return object being:

 return (
    <div className="flex">
      {objToArr(socials).map((social) => (
        <a href={social.url}>{social.name}</a>
      ))}
    </div>
  );
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文