admin管理员组文章数量:1355535
I want to introduce a multilingual system. I have a function ponent 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:
Is it possible to return this ponent as a something like string, which HTML forms would accept?
Is it possible to apply context consumer to pure JS function, so it does not return a React ponent, but a primitive value?
Translation ponent:
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.
I want to introduce a multilingual system. I have a function ponent 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:
Is it possible to return this ponent as a something like string, which HTML forms would accept?
Is it possible to apply context consumer to pure JS function, so it does not return a React ponent, but a primitive value?
Translation ponent:
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.
Share Improve this question edited Jun 8, 2019 at 7:18 Yilmaz 49.9k18 gold badges217 silver badges270 bronze badges asked Jun 6, 2019 at 21:37 ŁukaszŁukasz 1331 gold badge1 silver badge5 bronze badges 14-
2
Can you share some code? React can render a
string
object correctly. You are most likely trying to render thecontext
object or something else. – Arash Motamedi Commented Jun 6, 2019 at 21:39 -
Hard to help without code / context. However from what you're describing it sounds like you want to dynamically render a ponent based off its name.
const ComponentToRender = 'MyComponent';
and using it would be like<ComponentToRender />
. So if you have conditional elements to render you can pass just the ponentsstring
name and then render it – John Ruddell Commented Jun 6, 2019 at 21:42 - Sorry guys, I added some code. I guess the problem is that I am returning whole consumer, not only string element from translation object. – Łukasz Commented Jun 6, 2019 at 21:52
-
Or not. It always gives [object object] in form. Even if you do sth like
const Value = () => "value"
and pass it to input placeholder like<input type="text" placeholder={<Value />}
. :-( – Łukasz Commented Jun 6, 2019 at 22:07 -
In that case you would just call
Value
as afunction
instead of rendering it as aponent
:<input type="text" placeholder={Value()} />
– Brian Hadaway Commented Jun 6, 2019 at 22:30
3 Answers
Reset to default 0I can confirm it doesn't work - <option>
html element content can be "Text, possibly with escaped characters (like é
)."
React ponent can return only string, it's perfectly valid (and works as OP stated) ... but this use case is not supported.
Using ponents to just return a string is not a good choice. It can be ineffective when you need many translated strings in one ponent. React has to manage it as ponents, control props, render, make reconcilation etc. Many, following ponents (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 ponent 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.
I had a similar need where I had to support translated strings and wanted to return a "string" from a react ponent. I wanted to be able use the ponent with a typical function call and in the render
section. Here is what I ended up doing.
This is the react ponent which returns the "string" value. Side note: I'm using redux to store a dictionary of strings but you can use something else.
import { useSelector } from 'react-redux';
export function StringValue({ stringId }) {
const myStrings = useSelector((state) => state.strings);
// Note: do your own error handling as required
return myStrings[stringId];
}
Here is an example of how to use the ponent with a typical function call and as a ponent in render
:
import { StringValue} from 'StringValue';
...
export function MyComponent(){
...
return (
<>
{console.log('StringValue ', StringValue({ sId: 'myStringKey' }))}
<StringValue sId="myStringKey" />
...
How about the approach to separate the translation logic from the rendering logic. Instead of returning a ponent that contains the translation, you can create a translation function or custom hook that returns the translated string.
Using a Translation Function or Custom Hook For example, you could create a custom hook that reads the context and returns a function for fetching translation strings:
import React, { useContext } from 'react';
import { LanguageContext } from './LanguageProvider';
const useTranslation = () => {
const { language } = useContext(LanguageContext);
const translations = language === 'pl' ? plTranslation : enTranslation;
return (element) => translations[element];
};
export default useTranslation;
Then in your ponent you can do:
const MyComponent = () => {
const t = useTranslation();
return (
<select>
<option value="en">{t('globalLanguageEnglish')}</option>
{/* other options */}
</select>
);
};
This way, you’re directly obtaining a string from your translation system rather than trying to render a ponent into a string.
本文标签: javascriptIs there a way to return React Component as string instead of objectStack Overflow
版权声明:本文标题:javascript - Is there a way to return React Component as string instead of object? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1743979974a2571039.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论