另一个(轻量级)提案在 Typescript 中实现,基于 ES6 & Redux & Hooks & JSON,没有第三方依赖。
由于所选语言在 redux 状态下加载,因此更改语言变得非常快,无需渲染所有页面,而只需渲染受影响的文本。
第 1 部分: Redux 设置:
/src/shared/Types.tsx
export type Language = 'EN' | 'CA';
/src/store/actions/actionTypes.tsx
export const SET_LANGUAGE = 'SET_LANGUAGE';
/src/store/actions/language.tsx:
import * as actionTypes from './actionTypes';
import { Language } from '../../shared/Types';
export const setLanguage = (language: Language) => ({
type: actionTypes.SET_LANGUAGE,
language: language,
});
/src/store/reducers/language.tsx:
import * as actionTypes from '../action/actionTypes';
import { Language } from '../../shared/Types';
import { RootState } from './reducer';
import dataEN from '../../locales/en/translation.json';
import dataCA from '../../locales/ca/translation.json';
type rootState = RootState['language'];
interface State extends rootState { }
interface Action extends rootState {
type: string,
}
const initialState = {
language: 'EN' as Language,
data: dataEN,
};
const setLanguage = (state: State, action: Action) => {
let data;
switch (action.language) {
case 'EN':
data = dataEN;
break;
case 'CA':
data = dataCA;
break;
default:
break;
}
return {
...state,
...{ language: action.language,
data: data,
}
};
};
const reducer = (state = initialState, action: Action) => {
switch (action.type) {
case actionTypes.SET_LANGUAGE: return setLanguage(state, action);
default: return state;
}
};
export default reducer;
/src/store/reducers/reducer.tsx
import { useSelector, TypedUseSelectorHook } from 'react-redux';
import { Language } from '../../shared/Types';
export interface RootState {
language: {
language: Language,
data: any,
}
};
export const useTypedSelector: TypedUseSelectorHook<RootState> = useSelector;
/src/App.tsx
import React from 'react';
import { Provider } from 'react-redux';
import { createStore, combineReducers } from 'redux';
import languageReducer from './store/reducers/language';
import styles from './App.module.css';
// Set global state variables through Redux
const rootReducer = combineReducers({
language: languageReducer,
});
const store = createStore(rootReducer);
const App = () => {
return (
<Provider store={store}>
<div className={styles.App}>
// Your components
</div>
</Provider>
);
}
export default App;
第 2 部分:带有语言的下拉菜单。就我而言,我将此组件放在导航栏中,以便能够从任何屏幕更改语言:
/src/components/Navigation/Language.tsx
import React from 'react';
import { useDispatch } from 'react-redux';
import { setLanguage } from '../../store/action/language';
import { useTypedSelector } from '../../store/reducers/reducer';
import { Language as Lang } from '../../shared/Types';
import styles from './Language.module.css';
const Language = () => {
const dispatch = useDispatch();
const language = useTypedSelector(state => state.language.language);
return (
<div>
<select
className={styles.Select}
value={language}
onChange={e => dispatch(setLanguage(e.currentTarget.value as Lang))}>
<option value="EN">EN</option>
<option value="CA">CA</option>
</select>
</div>
);
};
export default Language;
第 3 部分: JSON 文件。在这个例子中,只是一个包含多种语言的测试值:
/src/locales/en/translation.json
{
"message": "Welcome"
}
/src/locales/ca/translation.json
{
"message": "Benvinguts"
}
第 4 部分:现在,在任何屏幕上,您都可以从 redux 设置中以所选语言显示文本:
import React from 'react';
import { useTypedSelector } from '../../store/reducers/reducer';
const Test = () => {
const t = useTypedSelector(state => state.language.data);
return (
<div> {t.message} </div>
)
}
export default Test;
对不起,帖子扩展,但我试图展示完整的设置以澄清所有疑问。完成此操作后,添加语言和在任何地方使用描述都非常快速和灵活。