Search code examples
reactjsinternationalizationreact-i18next

i18n react return [object object]


I have an object like this one :

{
 comment: "autogenerated"
 createdDate: "2021-09-21T14:32:47"
 id: 7831
 lastModifiedDate: "2021-09-21T14:32:47"
 media: "LETTER"
}

Knowing that media can return different values like: "LETTER", "PHONE" "EMAIL".

I would like my translation to change depending on the value returned by media

const renderMedia = (media: string) => {
   return (
    <>
      {t(`press.text`, {
        media: presentMedia(media),
      })}
    </>
   );
 };

The presentMedia() function returns a translation based on the value returned by media

 const presentMedia = (media: string) => {
      switch (media) {
       case 'PHONE':
        return <span>t('press.media.phone')</span>;

       case 'LETTER':
         return <span>{t('press.media.letter')}</span>;

       case 'EMAIL':
           return <span>t('press.media.email')</span>;
      }
     };

the i18n file :

 "press": {
   "text": "files {{media}}",
   "media": {
     "phone": " by phone",
     "letter": "bu letter",
     "email": "bu email"
   },

on the other hand the function presentMedia return [object, Object] while I thought to recover the translation present in the switch

if I replace <span>{t('press.media.letter')}</span> it with a simple string <span>test</span> it is displayed

is there a problem with using i18n React in a function ?

There may be another solution that would give me the same result?


Solution

  • Here you have one CodeSanbox with the example: https://codesandbox.io/s/cranky-allen-oujoc?file=/src/App.js

    The error is: presetMedia is returning a [object Object] because you're returning also the <span>. So, it's a React Node (or [objectObject])

    I'd recommend change:

     const presentMedia = (media: string) => {
          switch (media) {
           case 'PHONE':
            return <span>{t('press.media.phone')}</span>;
    
           case 'LETTER':
             return <span>{t('press.media.letter')}</span>;
    
           case 'EMAIL':
               return <span>{t('press.media.email')}</span>;
          }
         };
    
    

    to this:

    const presentMedia = (media: string) => {
      switch (media) {
        case 'PHONE':
          return t('press.media.phone');
    
        case 'LETTER':
          return t('press.media.letter');
    
        case 'EMAIL':
          return t('press.media.email');
      }
    };
    

    Finally, If it works, I'd suggest change to this:

    const presentMedia = (media: string) => t(`press.media.${media.toLowerCase()`);