React+Redux+react-redux-i18n报错“Error getting locale from store!”求助
解决React+Redux+react-redux-i18n的"Error getting locale from store!"问题
问题根源分析
从你提供的代码和排查信息来看,问题核心来自两点:
- 重复绑定store:在
add-provider-decorator.js和setup-localization.js的thunk中都调用了syncTranslationWithStore,导致react-redux-i18n与store的绑定逻辑冲突,内部读取locale时出现异常。 - Thunk内时序错误:在thunk中先调用
store.getState()再执行syncTranslationWithStore,且异步操作过程中react-redux-i18n可能提前尝试读取未初始化的store状态;同时在reducer执行期间调用store.getState()触发了额外错误。
具体修复步骤
1. 统一syncTranslationWithStore调用时机,移除重复绑定
只在store创建完成后调用一次syncTranslationWithStore,禁止在thunk内部重复执行:
- 保留
add-provider-decorator.js中store创建后的syncTranslationWithStore(store)调用。 - 删掉
setup-localization.js的thunk内部的syncTranslationWithStore(store);语句。
2. 调整Thunk逻辑顺序,避免非法读取state
修改localizationThunkCreator,给currentSelectedLanguage设置默认值,避免i18n状态未初始化时出错:
export const localizationThunkCreator = ( localizationAPI, updateLanguage, updateAvailableLanguages, setLocale, loadTranslations ) => async (store) => { const translations = await localizationAPI.fetchTranslationResource(); const localizationConfig = await localizationAPI.fetchLocalizationConfig(); // 读取state时增加默认值兜底 const currentState = store.getState(); const currentSelectedLanguage = selectLanguage(currentState) || localizationConfig.fallbackLanguage; const isCurrentlySelectedLanguageSupported = localizationConfig.availableLanguages .map((lang) => lang.value) .includes(currentSelectedLanguage); store.dispatch(loadTranslations(translations)); store.dispatch(updateAvailableLanguages(localizationConfig.availableLanguages)); const resultLanguage = isCurrentlySelectedLanguageSupported ? currentSelectedLanguage : localizationConfig.fallbackLanguage; store.dispatch(setLocale(resultLanguage)); store.dispatch(updateLanguage(resultLanguage)); };
3. 给i18n reducer设置初始默认值
确保store初始化时i18n状态有默认值,避免react-redux-i18n读取空状态:
// 修改add-provider-decorator.js中的store创建逻辑 const store = createStore( combineReducers({ i18n: i18nReducer }), // 添加初始状态兜底 { i18n: { locale: 'en', translations: {} } }, applyMiddleware(thunk) ); syncTranslationWithStore(store);
4. 确保Storybook装饰器在翻译加载完成后生效
调整add-provider-decorator.js的装饰器添加逻辑,确保翻译加载完成后再渲染组件:
const addProviderDecorator = () => { return fetchAndApplyTranslations().then(() => { const ProviderDecorator = (storyFn) => ( <Provider store={store}> {storyFn()} </Provider> ); addDecorator(ProviderDecorator); }); };
额外验证点
- 所有使用
translate高阶组件或t翻译函数的组件,必须包裹在Redux Provider内部。 - 确保应用根组件渲染前,已完成翻译加载和locale设置(比如在根组件的
componentDidMount中调用setupLocalization)。
内容的提问来源于stack exchange,提问作者mohan bhonu
相关产品推荐
相关产品推荐

