React类组件调用useTranslation报错,如何用i18next实现多语言切换按钮
报错原因
useTranslation是i18next提供的React Hook,而React Hook 仅支持在函数组件、自定义Hook中调用,不允许在类组件内部使用,你当前的Navibar是类组件,所以会触发该报错。
解决方案
方案1:将类组件改写为函数组件(推荐)
这是React官方当前推荐的写法,能更顺畅适配整个Hook生态,改写后代码示例:
import { useTranslation } from 'react-i18next'; // 其余依赖导入保持不变 export default function Navibar() { // 注意Hook必须放在组件顶层,不能写在嵌套函数或return之后 const { t, i18n } = useTranslation(); const changeLanguage = (lang) => { i18n.changeLanguage(lang); }; return ( <div className="navibar"> <Navbar collapseOnSelect expand="lg" bg="primary" variant="dark"> <Navbar fixed="top" /> <Navbar.Brand id="pad-laft">I House</Navbar.Brand> <Navbar.Toggle aria-controls="responsive-navbar-nav" /> <Navbar.Collapse id="responsive-navbar-nav"> <Nav className=""> <NavLink className="text-light"> <Link className="btn-header" to="/"> <HomeOutlined className="icon-header" /> {t("navibar.home")} </Link> </NavLink> <NavLink className="text-light"> <Link className="btn-header" to="/about"> <FileTextOutlined className="icon-header" /> biz haqimizda </Link> </NavLink> <NavLink className="text-light"> <Link className="btn-header" to="/courses"> <TeamOutlined className="icon-header" /> kurslar </Link> </NavLink> <NavLink className="text-light"> <Link className="btn-header" to="/faq"> <QuestionCircleOutlined className="icon-header" /> faq </Link> </NavLink> <NavLink className="text-light"> <Link className="btn-header" to="/contacts"> <PhoneOutlined className="icon-header" /> aloqa </Link> </NavLink> <button onClick={() => changeLanguage("uz")}>uz.....</button> <button onClick={() => changeLanguage("ru")}>ru.....</button> </Nav> </Navbar.Collapse> </Navbar> </div> ); }
方案2:保留类组件,使用withTranslation高阶组件注入能力
如果不想改动现有类组件的结构,可以用i18next提供的高阶组件withTranslation来包裹你的组件,t和i18n会通过props注入到组件内,示例代码:
import { withTranslation } from 'react-i18next'; // 其余依赖导入保持不变 class Navibar extends Component { render() { // 直接从props中取t和i18n即可 const { t, i18n } = this.props; const changeLanguage = (lang) => { i18n.changeLanguage(lang); }; // 原有return内的JSX代码完全不变,此处省略重复内容 return ( // 原有导航栏代码不变 ); } } // 导出时用withTranslation包裹组件即可,有自定义命名空间的话可以传入对应参数 export default withTranslation()(Navibar);
内容的提问来源于stack exchange,提问作者Asrorbek
相关产品推荐
相关产品推荐

