question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

React - Using <Trans> with object properties

See original GitHub issue

I haven’t had much luck doing

const component = (props) => {<Trans>Hello {props.user}</Trans>);

it always renders Hello undefined. However if I change it to

const component = ({user}) => (<Trans>Hello {user}</Trans>);

I get Hello Foo, which is the output I expected in the first case. Is this a bug that’s easy to fix? I’ll be happy to PR if you point me in the right direction.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:12 (12 by maintainers)

github_iconTop GitHub Comments

1reaction
tricoder42commented, Jul 4, 2017

I tried to generate name from expression, and it works:

      // src/index.js
      import generate from 'babel-generate'

      ...
 
      // line 236
      if (t.isIdentifier(exp) || t.isMemberExpression(exp)) {
        const name = generate(exp).code  // generate JS from AST
        const key = t.isIdentifier(exp) ? exp : t.stringLiteral(name)
        nextProps.text += `{${name}}`
        nextProps.values[name] = t.objectProperty(key, exp)
<Trans>Hello {props.name}</Trans>
// becomes
<Trans id="Hello {props.name}" values={{ "props.name": props.name }} />

It could literally works with any expression (the if condition just need to match other cases like CallExpressions, etc)

However, I don’t think it’s a good idea in general case. Ideally, all static values could be used as named arguments (variables, object properties, array indexes), while dynamic values (function calls) should be used as positional arguments. The reason is that we don’t know if function is pure:

<Trans>1st roll {random()}, 2nd roll {random()}</Trans>

// This won't work! random() in translation is called only once
<Trans id="1st roll {random()}, 2nd roll {random()}" values={{ "random()": random() }} />

// Now it works
<Trans id="1st roll {0}, 2nd roll {0}" values={{ "0": random(), "1": random() }} />

Problem is with object properties. ES6 introduces getters and they might have potentially side effects:

const props = {
  get random() {
    return Math.random()
  }
}

<Trans>1st roll {props.random}, 2nd roll {props.random}</Trans>
// and we're screwed again, props.random getter is called only once
<Trans id="1st roll {props.random}, 2nd roll {props.random}" values={{ "props.random": props.random }} />

It’s probably safer to use positional arguments everywhere except for simple identifiers. It has predictable behavior in all cases and if user wants to have variable name in translation, they’ll know how to achieve it.

@Peping What do you think?

1reaction
tricoder42commented, Jul 3, 2017

This isn’t bug, it’s known limitation (Link to new docs, but it’s also mentioned in old one)

However, this should at least raise an error or warning in console.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Trans Component - react-i18next documentation
This component enables you to nest any React content to be translated as one cohesive string. It supports both plural and interpolation. Let's...
Read more >
React components in i18next interpolation display as [object ...
You can't use t function in order to inject jsx . There is a special Trans component for this, you should use it....
Read more >
Common i18n patterns in React — LinguiJS documentation
Using jsx macros is the most straightforward way how to translate your React components. <Trans> handles translations of messages including variables and ...
Read more >
A Guide to React Localization with i18next | Phrase
We can also use data models, name/value objects, for interpolation. Let's refactor the code above to use a data model. public/locales/en/translation.json.
Read more >
How to Add Localization (l10n) to Your React App with react ...
Next, the use(initReactI18next) will bind react-i18next to the i18n instance. The first two properties of the init object parameter are a ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found