From 46e8ea5ff69325b73087811a2ce6a2b1faffa971 Mon Sep 17 00:00:00 2001 From: Viktor Andersson <30777521+VIKTORVAV99@users.noreply.github.com> Date: Mon, 15 Jul 2024 13:07:38 +0200 Subject: [PATCH] use arrow functions where possible (#1762) --- src/TransWithoutContext.js | 44 ++++++++++++++++++-------------------- src/context.js | 28 +++++++++++------------- src/defaults.js | 8 +++---- src/i18nInstance.js | 8 +++---- src/useSSR.js | 4 ++-- src/useTranslation.js | 18 +++++++--------- src/utils.js | 29 ++++++++++++------------- src/withSSR.js | 5 ++--- src/withTranslation.js | 5 ++--- 9 files changed, 67 insertions(+), 82 deletions(-) diff --git a/src/TransWithoutContext.js b/src/TransWithoutContext.js index 6e1f64731..e047913c0 100644 --- a/src/TransWithoutContext.js +++ b/src/TransWithoutContext.js @@ -4,36 +4,34 @@ import { warn, warnOnce } from './utils.js'; import { getDefaults } from './defaults.js'; import { getI18n } from './i18nInstance.js'; -function hasChildren(node, checkLength) { +const hasChildren = (node, checkLength) => { if (!node) return false; const base = node.props ? node.props.children : node.children; if (checkLength) return base.length > 0; return !!base; -} +}; -function getChildren(node) { +const getChildren = (node) => { if (!node) return []; const children = node.props ? node.props.children : node.children; return node.props && node.props.i18nIsDynamicList ? getAsArray(children) : children; -} +}; -function hasValidReactChildren(children) { +const hasValidReactChildren = (children) => { if (Object.prototype.toString.call(children) !== '[object Array]') return false; return children.every((child) => isValidElement(child)); -} +}; -function getAsArray(data) { - return Array.isArray(data) ? data : [data]; -} +const getAsArray = (data) => (Array.isArray(data) ? data : [data]); -function mergeProps(source, target) { +const mergeProps = (source, target) => { const newTarget = { ...target }; // overwrite source.props when target.props already set newTarget.props = Object.assign(source.props, target.props); return newTarget; -} +}; -export function nodesToString(children, i18nOptions) { +export const nodesToString = (children, i18nOptions) => { if (!children) return ''; let stringNode = ''; @@ -103,9 +101,9 @@ export function nodesToString(children, i18nOptions) { }); return stringNode; -} +}; -function renderNodes(children, targetString, i18n, i18nOptions, combinedTOpts, shouldUnescape) { +const renderNodes = (children, targetString, i18n, i18nOptions, combinedTOpts, shouldUnescape) => { if (targetString === '') return []; // check if contains tags we need to replace from html string to react nodes @@ -119,7 +117,7 @@ function renderNodes(children, targetString, i18n, i18nOptions, combinedTOpts, s // v2 -> interpolates upfront no need for "some <0>{{var}}"" -> will be just "some {{var}}" in translation file const data = {}; - function getData(childs) { + const getData = (childs) => { const childrenArray = getAsArray(childs); childrenArray.forEach((child) => { @@ -127,7 +125,7 @@ function renderNodes(children, targetString, i18n, i18nOptions, combinedTOpts, s if (hasChildren(child)) getData(getChildren(child)); else if (typeof child === 'object' && !isValidElement(child)) Object.assign(data, child); }); - } + }; getData(children); @@ -136,7 +134,7 @@ function renderNodes(children, targetString, i18n, i18nOptions, combinedTOpts, s const ast = HTML.parse(`<0>${targetString}`); const opts = { ...data, ...combinedTOpts }; - function renderInner(child, node, rootReactNode) { + const renderInner = (child, node, rootReactNode) => { const childs = getChildren(child); const mappedChildren = mapAST(childs, node.children, rootReactNode); // `mappedChildren` will always be empty if using the `i18nIsDynamicList` prop, @@ -145,9 +143,9 @@ function renderNodes(children, targetString, i18n, i18nOptions, combinedTOpts, s (child.props && child.props.i18nIsDynamicList) ? childs : mappedChildren; - } + }; - function pushTranslatedJSX(child, inner, mem, i, isVoid) { + const pushTranslatedJSX = (child, inner, mem, i, isVoid) => { if (child.dummy) { child.children = inner; // needed on preact! mem.push(cloneElement(child, { key: i }, isVoid ? undefined : inner)); @@ -169,12 +167,12 @@ function renderNodes(children, targetString, i18n, i18nOptions, combinedTOpts, s }), ); } - } + }; // reactNode (the jsx root element or child) // astNode (the translation string as html ast) // rootReactNode (the most outer jsx children array or trans components prop) - function mapAST(reactNode, astNode, rootReactNode) { + const mapAST = (reactNode, astNode, rootReactNode) => { const reactNodes = getAsArray(reactNode); const astNodes = getAsArray(astNode); @@ -291,7 +289,7 @@ function renderNodes(children, targetString, i18n, i18nOptions, combinedTOpts, s } return mem; }, []); - } + }; // call mapAST with having react nodes nested into additional node like // we did for the string ast from translation @@ -302,7 +300,7 @@ function renderNodes(children, targetString, i18n, i18nOptions, combinedTOpts, s getAsArray(children || []), ); return getChildren(result[0]); -} +}; export function Trans({ children, diff --git a/src/context.js b/src/context.js index e5aba8b8d..3b00a459f 100644 --- a/src/context.js +++ b/src/context.js @@ -18,27 +18,23 @@ export class ReportNamespaces { }); } - getUsedNamespaces() { - return Object.keys(this.usedNamespaces); - } + getUsedNamespaces = () => Object.keys(this.usedNamespaces); } -export function composeInitialProps(ForComponent) { - return async (ctx) => { - const componentsInitialProps = ForComponent.getInitialProps - ? await ForComponent.getInitialProps(ctx) - : {}; +export const composeInitialProps = (ForComponent) => async (ctx) => { + const componentsInitialProps = ForComponent.getInitialProps + ? await ForComponent.getInitialProps(ctx) + : {}; - const i18nInitialProps = getInitialProps(); + const i18nInitialProps = getInitialProps(); - return { - ...componentsInitialProps, - ...i18nInitialProps, - }; + return { + ...componentsInitialProps, + ...i18nInitialProps, }; -} +}; -export function getInitialProps() { +export const getInitialProps = () => { const i18n = getI18n(); const namespaces = i18n.reportNamespaces ? i18n.reportNamespaces.getUsedNamespaces() : []; @@ -55,4 +51,4 @@ export function getInitialProps() { ret.initialLanguage = i18n.language; return ret; -} +}; diff --git a/src/defaults.js b/src/defaults.js index 0d11c0188..66f8a3d72 100644 --- a/src/defaults.js +++ b/src/defaults.js @@ -13,10 +13,8 @@ let defaultOptions = { unescape, }; -export function setDefaults(options = {}) { +export const setDefaults = (options = {}) => { defaultOptions = { ...defaultOptions, ...options }; -} +}; -export function getDefaults() { - return defaultOptions; -} +export const getDefaults = () => defaultOptions; diff --git a/src/i18nInstance.js b/src/i18nInstance.js index 62171f6bd..f48a16dec 100644 --- a/src/i18nInstance.js +++ b/src/i18nInstance.js @@ -1,9 +1,7 @@ let i18nInstance; -export function setI18n(instance) { +export const setI18n = (instance) => { i18nInstance = instance; -} +}; -export function getI18n() { - return i18nInstance; -} +export const getI18n = () => i18nInstance; diff --git a/src/useSSR.js b/src/useSSR.js index 24f0ba310..b3da6f82f 100644 --- a/src/useSSR.js +++ b/src/useSSR.js @@ -1,7 +1,7 @@ import { useContext } from 'react'; import { getI18n, I18nContext } from './context.js'; -export function useSSR(initialI18nStore, initialLanguage, props = {}) { +export const useSSR = (initialI18nStore, initialLanguage, props = {}) => { const { i18n: i18nFromProps } = props; const { i18n: i18nFromContext } = useContext(I18nContext) || {}; const i18n = i18nFromProps || i18nFromContext || getI18n(); @@ -30,4 +30,4 @@ export function useSSR(initialI18nStore, initialLanguage, props = {}) { i18n.changeLanguage(initialLanguage); i18n.initializedLanguageOnce = true; } -} +}; diff --git a/src/useTranslation.js b/src/useTranslation.js index bc5c2267e..f41b7e07e 100644 --- a/src/useTranslation.js +++ b/src/useTranslation.js @@ -10,20 +10,18 @@ const usePrevious = (value, ignore) => { return ref.current; }; -function alwaysNewT(i18n, language, namespace, keyPrefix) { - return i18n.getFixedT(language, namespace, keyPrefix); -} +const alwaysNewT = (i18n, language, namespace, keyPrefix) => + i18n.getFixedT(language, namespace, keyPrefix); -function useMemoizedT(i18n, language, namespace, keyPrefix) { - return useCallback(alwaysNewT(i18n, language, namespace, keyPrefix), [ +const useMemoizedT = (i18n, language, namespace, keyPrefix) => + useCallback(alwaysNewT(i18n, language, namespace, keyPrefix), [ i18n, language, namespace, keyPrefix, ]); -} -export function useTranslation(ns, props = {}) { +export const useTranslation = (ns, props = {}) => { // assert we have the needed i18nInstance const { i18n: i18nFromProps } = props; const { i18n: i18nFromContext, defaultNS: defaultNSFromContext } = useContext(I18nContext) || {}; @@ -114,9 +112,9 @@ export function useTranslation(ns, props = {}) { setT(getNewT); } - function boundReset() { + const boundReset = () => { if (isMounted.current) setT(getNewT); - } + }; // bind events to trigger change, like languageChanged if (bindI18n && i18n) i18n.on(bindI18n, boundReset); @@ -161,4 +159,4 @@ export function useTranslation(ns, props = {}) { loadNamespaces(i18n, namespaces, () => resolve()); } }); -} +}; diff --git a/src/utils.js b/src/utils.js index f55dffe74..e6ab684a2 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,3 +1,4 @@ +// Do not use arrow function here as it will break optimizations of arguments export function warn(...args) { if (console && console.warn) { if (typeof args[0] === 'string') args[0] = `react-i18next:: ${args[0]}`; @@ -6,6 +7,7 @@ export function warn(...args) { } const alreadyWarned = {}; +// Do not use arrow function here as it will break optimizations of arguments export function warnOnce(...args) { if (typeof args[0] === 'string' && alreadyWarned[args[0]]) return; if (typeof args[0] === 'string') alreadyWarned[args[0]] = new Date(); @@ -37,22 +39,22 @@ const loadedClb = (i18n, cb) => () => { } }; -export function loadNamespaces(i18n, ns, cb) { +export const loadNamespaces = (i18n, ns, cb) => { i18n.loadNamespaces(ns, loadedClb(i18n, cb)); -} +}; // should work with I18NEXT >= v22.5.0 -export function loadLanguages(i18n, lng, ns, cb) { +export const loadLanguages = (i18n, lng, ns, cb) => { // eslint-disable-next-line no-param-reassign if (typeof ns === 'string') ns = [ns]; ns.forEach((n) => { if (i18n.options.ns.indexOf(n) < 0) i18n.options.ns.push(n); }); i18n.loadLanguages(lng, loadedClb(i18n, cb)); -} +}; // WAIT A LITTLE FOR I18NEXT BEING UPDATED IN THE WILD, before removing this old i18next version support -function oldI18nextHasLoadedNamespace(ns, i18n, options = {}) { +const oldI18nextHasLoadedNamespace = (ns, i18n, options = {}) => { const lng = i18n.languages[0]; const fallbackLng = i18n.options ? i18n.options.fallbackLng : false; const lastLng = i18n.languages[i18n.languages.length - 1]; @@ -91,9 +93,9 @@ function oldI18nextHasLoadedNamespace(ns, i18n, options = {}) { if (loadNotPending(lng, ns) && (!fallbackLng || loadNotPending(lastLng, ns))) return true; return false; -} +}; -export function hasLoadedNamespace(ns, i18n, options = {}) { +export const hasLoadedNamespace = (ns, i18n, options = {}) => { if (!i18n.languages || !i18n.languages.length) { warnOnce('i18n.languages were undefined or empty', i18n.languages); return true; @@ -120,12 +122,9 @@ export function hasLoadedNamespace(ns, i18n, options = {}) { return false; }, }); -} +}; -export function getDisplayName(Component) { - return ( - Component.displayName || - Component.name || - (typeof Component === 'string' && Component.length > 0 ? Component : 'Unknown') - ); -} +export const getDisplayName = (Component) => + Component.displayName || + Component.name || + (typeof Component === 'string' && Component.length > 0 ? Component : 'Unknown'); diff --git a/src/withSSR.js b/src/withSSR.js index db4d5b89c..dbad177cf 100644 --- a/src/withSSR.js +++ b/src/withSSR.js @@ -3,8 +3,8 @@ import { useSSR } from './useSSR.js'; import { composeInitialProps } from './context.js'; import { getDisplayName } from './utils.js'; -export function withSSR() { - return function Extend(WrappedComponent) { +export const withSSR = () => + function Extend(WrappedComponent) { function I18nextWithSSR({ initialI18nStore, initialLanguage, ...rest }) { useSSR(initialI18nStore, initialLanguage); @@ -19,4 +19,3 @@ export function withSSR() { return I18nextWithSSR; }; -} diff --git a/src/withTranslation.js b/src/withTranslation.js index 810208079..cedf5f4c7 100644 --- a/src/withTranslation.js +++ b/src/withTranslation.js @@ -2,8 +2,8 @@ import { createElement, forwardRef as forwardRefReact } from 'react'; import { useTranslation } from './useTranslation.js'; import { getDisplayName } from './utils.js'; -export function withTranslation(ns, options = {}) { - return function Extend(WrappedComponent) { +export const withTranslation = (ns, options = {}) => + function Extend(WrappedComponent) { function I18nextWithTranslation({ forwardedRef, ...rest }) { const [t, i18n, ready] = useTranslation(ns, { ...rest, keyPrefix: options.keyPrefix }); @@ -33,4 +33,3 @@ export function withTranslation(ns, options = {}) { return options.withRef ? forwardRefReact(forwardRef) : I18nextWithTranslation; }; -}