Repository: i18next/react-i18next (JavaScript)

Issue:
Unable to provide default value for Trans without i18nKey
## 🐛 Bug Report
At the company I'm working at, we're using key fallback for all of our translations as this allows us to keep the strings inside the code. We're also using the pluralize library to allow us to leave our English resource file empty.

Here's an example using `t`:
```ts
t('You have {{count}} message', {
  count,
  defaultValue: `You have ${count} ${pluralize('message', count)}`,
});
```

The above works fine with `t`, but does not work with the Trans component since the key defaults to the `defaults` prop.

## To Reproduce
```ts
<Trans
  count={count}
  defaults={`You have ${count} ${pluralize('message', count)}`}
>
  You have {{ count }} message
</Trans>
```

## Expected behavior
I expect the key to be `You have {{count}} message`, but the key that react-i18next uses in the `t` call is `You have 3 messages` (if `count` is 3, for example).


## Proposed solutions
1. **(breaking change)** Rather than defaulting the key to the `defaults` prop [here](https://github.com/i18next/react-i18next/blob/52d514c64ac15dadfe5cb263918c0d5ce06125e4/src/TransWithoutContext.js#L337), default to `nodesToString(children, reactI18nextOptions)`.
2. Add a `defaultValue` prop that behaves similar to the one in `t` (i.e. does not get used as the key).

I can open a PR for this if we decide on a solution.


Discussion:
Feel free to open a PR, but this type of pluralization handling will only work for english.
Btw. No braking change for that.



Patch:
diff --git a/src/TransWithoutContext.js b/src/TransWithoutContext.js
index 8c1d81d7a..70e17458a 100644
--- a/src/TransWithoutContext.js
+++ b/src/TransWithoutContext.js
@@ -328,13 +328,11 @@ export function Trans({
   let namespaces = ns || t.ns || (i18n.options && i18n.options.defaultNS);
   namespaces = typeof namespaces === 'string' ? [namespaces] : namespaces || ['translation'];
 
+  const nodeAsString = nodesToString(children, reactI18nextOptions);
   const defaultValue =
-    defaults ||
-    nodesToString(children, reactI18nextOptions) ||
-    reactI18nextOptions.transEmptyNodeValue ||
-    i18nKey;
+    defaults || nodeAsString || reactI18nextOptions.transEmptyNodeValue || i18nKey;
   const { hashTransKey } = reactI18nextOptions;
-  const key = i18nKey || (hashTransKey ? hashTransKey(defaultValue) : defaultValue);
+  const key = i18nKey || (hashTransKey ? hashTransKey(nodeAsString) : nodeAsString);
   const interpolationOverride = values
     ? tOptions.interpolation
     : { interpolation: { ...tOptions.interpolation, prefix: '#$?', suffix: '?$#' } };


Test patch:
diff --git a/test/i18n.js b/test/i18n.js
index 26d727e2d..969030c88 100644
--- a/test/i18n.js
+++ b/test/i18n.js
@@ -47,6 +47,8 @@ i18n.init({
         transTestCustomUnescapeSecond: 'Vertrauens&shy;kennwert',
         testTransWithCtx: 'Go <1>there</1>.',
         testTransWithCtx_home: 'Go <1>home</1>.',
+        'You have {{count}} message_one': 'You have {{count}} message',
+        'You have {{count}} message_other': 'You have {{count}} messages',
         deepPath: {
           deepKey1: 'value1',
         },
diff --git a/test/trans.render.spec.js b/test/trans.render.spec.js
index 564c181a9..9361eae00 100644
--- a/test/trans.render.spec.js
+++ b/test/trans.render.spec.js
@@ -755,3 +755,22 @@ describe('trans with context property', () => {
     `);
   });
 });
+
+describe('trans with defaults property and children', () => {
+  function TestComponent() {
+    return (
+      <Trans count={3} defaults="This property should not get used">
+        You have {{ count: 3 }} message
+      </Trans>
+    );
+  }
+
+  it('should render correct content', () => {
+    const { container } = render(<TestComponent />);
+    expect(container.firstChild).toMatchInlineSnapshot(`
+      <div>
+        You have 3 messages
+      </div>
+    `);
+  });
+});