#javascript #json #reactjs #dictionary #i18next
#javascript #json #reactjs #словарь #i18next
Вопрос:
Yarn start
вызывает периодические ошибки. В код, вызывающий ошибку, не было внесено никаких исправлений.
Также часто сохраняется и перекомпилируется код из других файлов. Время от времени вы можете выполнять рендеринг без каких-либо проблем.
Ошибка
Изображение предупреждения консоли
Ошибка типа: t(…).map не является функцией
* Пожалуйста, проверьте изображение.
Я создал карту файла json, который i18next использует для перевода.
i18next: hasLoadedNamespace: i18next was not initialized undefined
,
key "about" for languages "en" won't get resolved as namespace "header" was not yet loaded This means something IS WRONG in your setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!
выводится с консоли с ошибкой, упомянутой ранее.
Package.json
{
"name": "homepage",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
"@types/i18next": "^13.0.0",
"@types/react-i18next": "^8.1.0",
"i18next": "^19.8.4",
"i18next-xhr-backend": "^3.2.2",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-i18next": "^11.7.4",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.1",
"styled-components": "^5.2.1",
"web-vitals": "^0.2.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@types/react": "^17.0.0",
"@types/react-router-dom": "^5.1.6",
"@types/styled-components": "^5.1.4",
"@typescript-eslint/eslint-plugin": "^4.9.0",
"@typescript-eslint/parser": "^4.9.0",
"eslint": "^7.14.0",
"eslint-config-airbnb": "^18.2.1",
"eslint-config-airbnb-typescript": "^12.0.0",
"eslint-config-prettier": "^6.15.0",
"eslint-config-react-app": "^6.0.0",
"eslint-import-resolver-alias": "^1.1.2",
"eslint-import-resolver-typescript": "^2.3.0",
"eslint-loader": "^4.0.2",
"eslint-plugin-flowtype": "^5.2.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-prettier": "^3.1.4",
"eslint-plugin-react": "^7.21.5",
"eslint-plugin-react-hooks": "^4.2.0",
"prettier": "^2.2.1",
"prettier-eslint": "^12.0.0",
"prettier-eslint-cli": "^5.0.0"
}
}
Реж
root
|-public
| |-locales
| |-productWS
| |-en.json
| |-ko.json
|-src
| |-components
| | |-MwsCard.tsx
| |-systems
| | |-ProductWs.ts
| |-i18n.ts
ru.json
{
"miniTitle":"ABC",
"title":"ABCDEFG",
"text": "abcdefg",
"version":[
{
"name": "1",
"sensor": ["1", "2", "3", "4", "5"],
"src":"/img/1.jpg"
},
{
"name": "2",
"sensor": ["1", "2", "3", "4", "5", "6", "7"],
"src":"/img/2.jpg"
}
]
}
ProductWs.tsx
import React from 'react';
import { useTranslation } from 'react-i18next';
import { MwsCard } from '../../components';
import { Wrap, Container, TitleH5, TitleH2, TextP1, CardContainer } from './ProductWsStyle';
interface VersionProps {
name: string;
sensor: string[];
src: string;
}
function ProductWs() {
const { t } = useTranslation('productWsDB');
return (
<Wrap>
<Container>
<TitleH5>{t('miniTitle')}</TitleH5>
<TitleH2>{t('title')}</TitleH2>
<TextP1>{t('text')}</TextP1>
<CardContainer>
****Error point---------------
{t<VersionProps[]>('version', { returnObjects: true }).map(item => (
<MwsCard key={item.name} name={item.name} sensor={item.sensor} src={item.src} />
))}
****Error point---------------
</CardContainer>
</Container>
</Wrap>
);
}
export default ProductWs;
MwsCard.tsx
import React from 'react';
import * as S from './MwsCardStyle';
import { Version } from './MwsProdDBType';
function MwsCard({ name, sensor, src }: Version) {
return (
<S.Container>
<S.Img src={src} alt={name} />
<S.Info>
<S.Title>{name}</S.Title>
{sensor.map(item => (
<S.Spec key={item}>{item}</S.Spec>
))}
</S.Info>
</S.Container>
);
}
export default MwsCard;
i18n.ts
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import backend from 'i18next-xhr-backend';
const userLanguage = window.navigator.language;
i18n
.use(backend)
.use(initReactI18next)
.init({
lng: localStorage.getItem('language') || userLanguage || 'en',
fallbackLng: 'en',
debug: true,
keySeparator: '.',
interpolation: {
escapeValue: false,
},
react: {
wait: true,
useSuspense: false,
},
backend: {
loadPath: '/locales/{{ns}}/{{lng}}.json',
},
});
export default i18n;
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './i18n';
import App from './App';
import reportWebVitals from './reportWebVitals';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root'),
);
reportWebVitals();
app.js
import React, { Suspense } from 'react';
import Routes from './Routes';
import Theme from './global-styles/Theme';
import './global-styles/import-fonts.css';
import { GlobalStyle } from './global-styles/GlobalStyle';
function App() {
return (
<Suspense fallback={<div>Loading...</div>} maxDuration={5000}>
<Theme>
<GlobalStyle />
<Routes />
</Theme>
</Suspense>
);
}
export default App;
Ответ №1:
Вам нужно добавить поставщика i18next в ваше дерево реакции.
import React from 'react';
import ReactDOM from 'react-dom';
import { I18nextProvider } from 'react-i18next';
import './i18n';
import App from './App';
import reportWebVitals from './reportWebVitals';
ReactDOM.render(
<React.StrictMode>
<I18nextProvider i18n={i18n}>
// ---^
<App />
</I18nextProvider>
</React.StrictMode>,
document.getElementById('root'),
);
reportWebVitals();
Комментарии:
1. Спасибо за ваш ответ. Однако ответ не помог. Изменение ‘useSuspense’ в ‘i18n.ts’ на true устранило все ошибки.