React:调用自定义函数返回undefined问题咨询(react-i18n场景)
问题分析与解决
核心问题
- Hook使用违规:
useTranslation是React Hook,必须在React组件顶层或自定义Hook中调用,不能在普通函数(如你的getLanguage)或Redux reducer这类纯函数里执行,否则会导致Hook调用环境错误,返回undefined或直接报错。 - 函数未执行:你的代码中
console.log(getLanguage)只是打印函数本身,没有调用函数,正确写法应为console.log(getLanguage())——但即使调用,也会因Hook规则问题报错。
解决方案
方案1:直接使用i18next实例(推荐)
跳过React Hook,直接导入i18n核心实例获取当前语言,可在任何普通函数、reducer中使用:
修改LanguageHandler.js:
// 导入与你初始化i18n一致的实例 import i18n from 'i18next'; export default function getLanguage() { return i18n.resolvedLanguage; }
在reducer中调用函数(注意执行函数):
import getLanguage from '../languages/LanguageHandler' export const getText = (state, id) => { const currentLang = getLanguage(); console.log(currentLang); // 此时会输出'en'或当前语言 return state.text[id][currentLang]; // 假设text结构按语言键存储 }
方案2:将语言存入Redux state
把当前语言同步到Redux状态中,让reducer直接从state读取:
- 在组件中同步语言到Redux:
import { useTranslation } from 'react-i18next'; import { useDispatch } from 'react-redux'; import { useEffect } from 'react'; function SomeComponent() { const { i18n } = useTranslation(); const dispatch = useDispatch(); useEffect(() => { dispatch({ type: 'SET_LANGUAGE', payload: i18n.resolvedLanguage }); }, [i18n.resolvedLanguage, dispatch]); }
- 在根reducer中添加语言状态:
const initialState = { language: 'en', // 其他状态... }; function rootReducer(state = initialState, action) { switch(action.type) { case 'SET_LANGUAGE': return { ...state, language: action.payload }; default: return state; } }
- 在
getText中直接读取state里的语言:
export const getText = (state, id) => { console.log(state.language); return state.text[id][state.language]; }
方案3:调用getText时传入语言
在组件中获取语言后作为参数传递,保持reducer的纯函数特性:
// 组件中 import { useTranslation } from 'react-i18next'; import { useSelector } from 'react-redux'; import { getText } from './textReducer'; function SomeComponent() { const { i18n } = useTranslation(); const state = useSelector(state => state); const text = getText(state, 'some-id', i18n.resolvedLanguage); }
修改getText:
export const getText = (state, id, language) => { console.log(language); return state.text[id][language]; }
内容的提问来源于stack exchange,提问作者Orl13
相关产品推荐
相关产品推荐

