在 React-Admin v3 中设置页面加载区域

Setting locale on page load in React-Admin v3

我一直在使用 React-Admin v2,现在是时候升级到下一个主要版本了。我的应用程序具有在页面加载时更改登录页面语言的功能,例如根据 url 参数。如果没有设置任何参数,语言将为英语,但如果 url 例如 myproject.tld/login/fi,则语言将为芬兰语。通过使用 changeLocale 动作创建者调度 CHANGE_LOCALE 动作,在 componentDidMount 中更改语言。

但是,我已经阅读了升级指南,它说翻译系统将不再以同样的方式工作,no longer uses redux。我已经能够熟悉新系统,并且我设法创建了用于更改语言的按钮,并且它起作用了。创建语言环境切换器函数并在其中使用钩子 useSetLocale 很容易。

但是,我仍然有这样的情况,即必须在没有任何用户操作(即单击按钮)的情况下即时更改语言。如果我无法根据 link 用户点击并登陆网站来翻译登录页面,我可以接受这个事实。默认是英语,如果用户想看到其他语言的登录表单,我可以在右上角创建语言 links。

更重要的还是在用户登录后更改UI语言。每个用户都将他们选择的语言保存到后端的用户对象中,成功登录后我的 React 应用程序知道语言代码。

主要问题:如何在登录后更改语言并仅在加载所有内容后更改语言?如果我理解正确的话,钩子不能在 componentDidMount 中使用。我目前知道的更改语言的方法是 1. 钩子 useSetLocale 和 2. 在 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 没有提供任何系统来这样做,但是你可以按照你想要的任何方式来做,例如使用本地存储。

例如,假设您的 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() 的组件中的默认布局:

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>
);