如何让react-i18next动态渲染来自state的翻译内容?
问题描述
我的React组件state中存储了如下数据:
[ { "id": 1, "title": "title1", "detail": { "en": "english detail1", "es": "catalan1" } }, { "id": 2, "title": "title2", "detail": { "en": "english detail2", "es": "catalan2" } } ]
我想让react-i18next直接使用state里的这些翻译数据,但尝试用<p>{t(${el.detail})}</p>调用时,返回结果是[object Object]。请问该如何让react-i18next从state(或其他动态数据源)中获取翻译内容,而非从固定的i18n.js配置文件读取?
解决方案
方法一:直接根据当前语言读取state字段
你的state数据已经按语言键(en/es)存储了对应翻译,最直接的方式是获取当前i18n的语言标识,直接从detail对象中取值:
import { useTranslation } from 'react-i18next'; import { useState } from 'react'; function YourComponent() { const { i18n } = useTranslation(); const [data, setData] = useState([/* 你的state数据 */]); return ( <div> {data.map(el => ( <p key={el.id}>{el.detail[i18n.language]}</p> ))} </div> ); }
这种方式无需依赖react-i18next的t函数,直接通过语言键映射取值,适配你的数据结构,简单高效。
方法二:动态更新i18next资源库
如果必须使用t函数调用,可以将state数据转换为i18next支持的资源格式,再动态注入到i18n实例中:
- 先编写数据转换函数,将state结构转为i18next资源格式:
const convertToI18nResources = (data) => { const resources = { en: { translation: {} }, es: { translation: {} } }; data.forEach(item => { // 用item.id作为翻译键,确保唯一性 resources.en.translation[`detail_${item.id}`] = item.detail.en; resources.es.translation[`detail_${item.id}`] = item.detail.es; }); return resources; };
- 在组件中动态更新i18n资源:
import { useTranslation, initReactI18next } from 'react-i18next'; import i18n from 'i18next'; import { useState, useEffect } from 'react'; // 初始化基础i18n配置(未初始化时执行) i18n.use(initReactI18next).init({ fallbackLng: 'en', interpolation: { escapeValue: false } }); function YourComponent() { const { t, i18n } = useTranslation(); const [data, setData] = useState([/* 你的state数据 */]); // 数据变化时更新i18n资源 useEffect(() => { const resources = convertToI18nResources(data); // 将转换后的资源合并到i18n实例 i18n.addResources('en', 'translation', resources.en.translation); i18n.addResources('es', 'translation', resources.es.translation); }, [data, i18n]); return ( <div> {data.map(el => ( <p key={el.id}>{t(`detail_${el.id}`)}</p> ))} </div> ); }
关于你之前的错误
你写的<p>{t(${el.detail})}</p>返回[object Object],是因为你把整个detail对象转成了字符串,而t函数接收的是翻译键名,不是对象本身,所以才会出现这个问题。
内容的提问来源于stack exchange,提问作者bebeadonis
相关产品推荐
相关产品推荐

