Skip to content

Commit

Permalink
fix hooks in case invalid lng and fallbacklng is false
Browse files Browse the repository at this point in the history
  • Loading branch information
jamuhl committed Jan 17, 2019
1 parent b8eddc9 commit 376fe57
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 34 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
### next
### 9.0.3

- fix useSSR for hooks storing state on i18n instance and not globally [671](https://github.com/i18next/react-i18next/issues/671)
- should fix case where fallbackLng is set false and invalid lng is loaded in hooks -> never ready [677](https://github.com/i18next/react-i18next/issues/677)
- multiple typescript improvements

### 9.0.2

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-i18next",
"version": "9.0.2",
"version": "9.0.3",
"description": "Internationalization for react done right. Using the i18next i18n ecosystem.",
"main": "dist/commonjs/index.js",
"types": "src/index.d.ts",
Expand Down
65 changes: 33 additions & 32 deletions src/hooks/useTranslation.js
Original file line number Diff line number Diff line change
@@ -1,41 +1,41 @@
import { useState, useEffect } from 'react';
import { getI18n, getDefaults, addUsedNamespaces } from './context';
import { warnOnce } from './utils';
import { useState, useEffect } from 'react'
import { getI18n, getDefaults, addUsedNamespaces } from './context'
import { warnOnce } from './utils'

function loadNamespaces(i18n, ns, cb) {
i18n.loadNamespaces(ns, () => {
// delay ready if not yet initialized i18n instance
if (i18n.isInitialized) {
cb();
cb()
} else {
const initialized = () => {
// due to emitter removing issue in i18next we need to delay remove
setImmediate(() => {
i18n.off('initialized', initialized);
});
cb();
};
i18n.off('initialized', initialized)
})
cb()
}

i18n.on('initialized', initialized);
i18n.on('initialized', initialized)
}
});
})
}

export function useTranslation(ns) {
// assert we have the needed i18nInstance
const i18n = getI18n();
const i18n = getI18n()
if (!i18n) {
warnOnce('You will need pass in an i18next instance by using i18nextReactModule');
return [k => k, {}];
warnOnce('You will need pass in an i18next instance by using i18nextReactModule')
return [k => k, {}]
}
const i18nOptions = getDefaults();
const i18nOptions = getDefaults()

// prepare having a namespace
let namespaces = ns || (i18n.options && i18n.options.defaultNS);
namespaces = typeof namespaces === 'string' ? [namespaces] : namespaces || ['translation'];
let namespaces = ns || (i18n.options && i18n.options.defaultNS)
namespaces = typeof namespaces === 'string' ? [namespaces] : namespaces || ['translation']

// report namespaces as used
addUsedNamespaces(namespaces);
addUsedNamespaces(namespaces)

// are we ready? yes if all namespaces in first language are loaded already (either with data or empty objedt on failed load)
const ready =
Expand All @@ -48,40 +48,41 @@ export function useTranslation(ns) {
(i18n.services.backendConnector.backend &&
i18n.services.backendConnector.state[`${i18n.languages[0]}|${n}`] &&
i18n.services.backendConnector.state[`${i18n.languages[0]}|${n}`] !== 1 &&
i18n.hasResourceBundle(i18n.languages[i18n.languages.length - 1], n)); // we have at least tried to load it and have a fallback
((i18n.options && !i18n.options.fallbackLng) ||
i18n.hasResourceBundle(i18n.languages[i18n.languages.length - 1], n))) // we have at least tried to load it and have a fallback if fallbackLng is set

return ret;
});
return ret
})

// set states
const [t, setT] = useState({ t: i18n.getFixedT(null, namespaces[0]) }); // seems we can't have functions as value -> wrap it in obj
const [t, setT] = useState({ t: i18n.getFixedT(null, namespaces[0]) }) // seems we can't have functions as value -> wrap it in obj

function resetT() {
setT({ t: i18n.getFixedT(null, namespaces[0]) });
setT({ t: i18n.getFixedT(null, namespaces[0]) })
}

useEffect(() => {
// bind events to trigger change, like languageChanged
if (i18nOptions.bindI18n && i18n) i18n.on(i18nOptions.bindI18n, resetT);
if (i18nOptions.bindI18n && i18n) i18n.on(i18nOptions.bindI18n, resetT)

// unbinding
return () => {
if (i18nOptions.bindI18n) {
const p = i18nOptions.bindI18n.split(' ');
p.forEach(f => i18n.off(f, resetT));
const p = i18nOptions.bindI18n.split(' ')
p.forEach(f => i18n.off(f, resetT))
}
};
});
}
})

// return hook stuff if ready or
// not yet loaded namespaces -> load them -> and trigger suspense
if (ready) {
return [t.t, i18n];
return [t.t, i18n]
}
throw new Promise(resolve => {
loadNamespaces(i18n, namespaces, () => {
resetT();
resolve();
});
});
resetT()
resolve()
})
})
}

0 comments on commit 376fe57

Please sign in to comment.