locale - 在 React-Admin v3 中设置页面加载的语言环境
问题描述
我一直在使用 React-Admin v2,现在是时候升级到下一个主要版本了。我的应用程序具有在页面加载时更改登录页面语言的功能,例如取决于 url 参数。如果没有设置任何参数,则语言将为英语,但如果 URL 为例如 myproject.tld/login/fi,则语言将为芬兰语。通过使用动作创建者componentDidMount
调度动作,语言在内部被改变。CHANGE_LOCALE
changeLocale
但是,我已经阅读了升级指南,它说翻译系统将不再以相同的方式工作,它不再使用 redux。我已经能够熟悉新系统,并且我设法创建了语言更改按钮,并且它起作用了。创建语言环境切换器功能并useSetLocale
在其中使用钩子很容易。
但是,我仍然有一些情况,即必须在没有任何用户操作的情况下即时更改语言,这意味着单击按钮。如果我不能根据用户点击并登陆到网站的链接来翻译登录页面,我可以接受这个事实。默认为英语,如果用户想查看其他语言的登录表单,我可以在右上角创建语言链接。
更重要的是在用户登录后更改 UI 语言。每个用户都将他们选择的语言保存到后端的用户对象中,成功登录后,我的 React 应用程序知道语言代码。
主要问题:如何在登录后更改语言并且仅在加载所有内容之后?如果我理解正确,钩子不能用于例如componentDidMount
. 我目前知道的更改语言的方法是 1. 钩子和 2. 在文件useSetLocale
中初始化它,如下所示:App.js
import * as React from "react";
import { Admin, Resource } from 'react-admin';
import polyglotI18nProvider from 'ra-i18n-polyglot';
import jsonServerProvider from 'ra-data-json-server';
import UserList from './users';
import englishMessages from 'ra-language-english';
import finnishMessages from 'ra-language-finnish';
const messages = {
fi: finnishMessages,
en: englishMessages,
};
const dataProvider = jsonServerProvider('https://jsonplaceholder.typicode.com');
const i18nProvider = polyglotI18nProvider(locale => messages[locale], "en");
const App = () => (
<Admin
dataProvider={dataProvider}
i18nProvider={i18nProvider}
>
<Resource name="users" list={UserList} />
</Admin>
);
export default App;
当然,这只是一个测试代码,该代码目前没有使用我的真实后端。但是有没有办法在成功登录后以及用户选择的语言已知时更改语言?是否有第三种强制语言的方法,或者我可以以某种方式重新初始化i18nProvider
默认设置为使用英语的语言?
解决方案
因此,您基本上是在尝试在authProvider
(获取用户偏好)和i18nProvider
. React-admin 没有提供任何系统来执行此操作,但您可以按照您想要的任何方式执行此操作,例如使用 localStorage。
例如,假设您的 authProvider 在登录时获取用户区域设置。它应该将其存储在 localStorage 中:
const authProvider = {
login: async ({ username, password }) => {
// fetch the auth API and grab the user locale in the response, then
localStorage.setItem('locale', locale);
},
// ...
}
接下来,您需要在应用挂载时执行效果(更改语言环境)。最好的地方是在应用程序布局中。以下是如何将默认布局包装在另一个调用i18nProvider.setLocale()
mount 的组件中:
import React, { useEffect } from 'react';
import { Layout, useSetLocale } from 'react-admin';
const MyLayout = props => {
const setLocale = useSetLocale();
useEffect(() => {
const locale = localStorage.getItem('locale');
setLocale(locale);
}, [setLocale]); // execute on mount
return <Layout {...props} />;
}
然后,您只需将自定义布局插入<Admin>
组件中,如下所示:
const App = () => (
<Admin
layout={MyLayout}
dataProvider={dataProvider}
i18nProvider={i18nProvider}
>
<Resource name="users" list={UserList} />
</Admin>
);
推荐阅读
- python - 我需要找到函数参数是否具有返回类型或不使用 Pycparser。我将如何做到这一点?
- python - 在 Python 中使用 Neyman-Pearson
- java - 为什么我的方法在我的 API 中有效,但在测试类中无效?
- javascript - 如何将字符串对象转换为对象?
- python-3.x - 根据用户输入中的整数删除列表中的数据
- typescript - 打字稿将异步函数结果分配给变量
- css - 谷歌字体和字体显示
- laravel - Laravel8上的supervisorctl处理作业队列问题
- javascript - 无法完全理解 Javascript 中的 Promise
- swift - Swift 中的图像调整大小仅适用于某些 iPhone 型号