Is there a way to return React Component as string instead of object?

Viewed 8809

I want to introduce a multilingual system. I have a function component that returns a translation of a specific element based on selected language (from Context API).

Everything works well until I put the translated element into the form (option value, placeholder, etc.) - then it appears as an [object object].

That's where 2 questions are born:

  1. Is it possible to return this component as a something like string, which HTML forms would accept?

  2. Is it possible to apply context consumer to pure JS function, so it does not return a React component, but a primitive value?

Translation component:

const Translation = ({ element }) => {
  let translation;

  return (
    <LanguageConsumer>
      {({ language }) => {
        switch (language) {
          case "pl":
            translation = plTranslation;
            break;

          case "en":
            translation = enTranslation;
            break;

          default:
            translation = enTranslation;
        }

        return translation[element];
      }}
    </LanguageConsumer>
  );
};

Example:

<option value="en">
  <Translation element="globalLanguageEnglish" />
</option>

Thanks in advance for your help.

1 Answers

I can confirm it doesn't work - <option> html element content can be "Text, possibly with escaped characters (like &eacute;)."

React component can return only string, it's perfectly valid (and works as OP stated) ... but this use case is not supported.

Using components to just return a string is not a good choice. It can be ineffective when you need many translated strings in one component. React has to manage it as components, control props, render, make reconcilation etc. Many, following components (siblings) of the same type (only different props) should be key-ed.

Smarter solution: In this case pass an array of options (keys) as prop and use one component to render all translated <option> elements in a loop (return using fragment), f.e. like this:

// get some translation fn f.e. from context
return (
  <>
    {props.items.map( item => <option key="{item}" value="{item}">{translate(item)}</option> )}
  </>
)

Look how it's done at ready i18n solutions like i18next described here - pass function 't' and use it to access your translations.

Related