React Native如何创建可复用Context模板适配不同父页面组件?
方案1:无Context最简实现(推荐)
你当前每个页面单独包裹Context的操作其实是冗余的,完全可以通过通用自定义Hook直接获取指定页面的多语言文案,省去所有重复的Context创建、Provider包裹逻辑。
步骤1:统一管理所有多语言资源
先在i18n根目录创建索引文件,按「语言-页面模块」的结构预注册所有页面的多语言文案,保持和你现有目录结构兼容:
// /i18n/index.js const i18nResources = { french: { // 格式为 页面模块路径: 对应语言的文案资源 'auth/entrance': require('./french/auth/entrance/i18n').default, 'auth/login': require('./french/auth/login/i18n').default, // 后续新增页面仅需要在此补充对应语言的条目即可 }, english: { 'auth/entrance': require('./english/auth/entrance/i18n').default, 'auth/login': require('./english/auth/login/i18n').default, }, spanish: { 'auth/entrance': require('./spanish/auth/entrance/i18n').default, 'auth/login': require('./spanish/auth/login/i18n').default, }, wolof: { 'auth/entrance': require('./wolof/auth/entrance/i18n').default, 'auth/login': require('./wolof/auth/login/i18n').default, } } // 通用获取指定模块对应语言文案的方法 export const getModuleLang = (lang, modulePath) => { return i18nResources[lang]?.[modulePath] || i18nResources.french[modulePath] }
步骤2:创建全局通用多语言Hook
// /utils/language/useLang.js import { useSelector } from "react-redux"; import { getTranslation } from "../../redux/reducers/translation/selector/selector"; import { getModuleLang } from "../../i18n"; // 传入页面模块路径即可返回对应模块的当前语言文案 export const useLang = (modulePath) => { const currentLang = useSelector(getTranslation).lang; return getModuleLang(currentLang, modulePath); }
业务组件使用示例
无需再给页面包裹任何Provider,直接在子组件中调用Hook传入当前模块路径即可:
import React from "react"; import { Text, TouchableOpacity } from "react-native"; import { useNavigation } from "@react-navigation/native"; // 引入通用Hook import { useLang } from "../../../../utils/language/useLang"; import { styles } from "./Style"; export default function Button() { // 传入当前所属页面的模块路径,直接拿到对应文案 const lang = useLang('auth/entrance'); const navigation = useNavigation(); return ( <TouchableOpacity style={styles.container} onPress={() => navigation.navigate("LoginNavigator")} > <Text style={styles.text}>{lang.login}</Text> </TouchableOpacity> ); }
方案2:通用Context工厂函数(适合需要Context隔离的场景)
如果你有特殊需求必须要按页面用Context隔离,可以创建通用的Context生成工厂,后续每个页面仅需要传入自身的多语言资源配置,即可批量生成对应的Provider和Hook,无需重复写Context创建逻辑。
通用工厂实现
// /utils/language/createLangContext.js import React, { useContext, createContext } from "react"; import { useSelector } from "react-redux"; import { getTranslation } from "../../redux/reducers/translation/selector/selector"; // 入参为当前页面的多语言资源匹配函数 export const createLangContext = (getModuleResource) => { const Context = createContext(); const useLanguageContext = () => useContext(Context); const LanguageProvider = ({ children }) => { const currentLang = useSelector(getTranslation).lang; const langResource = getModuleResource(currentLang); return <Context.Provider value={langResource}>{children}</Context.Provider>; }; return { useLanguageContext, LanguageProvider }; };
单页面使用示例
每个页面仅需要几行代码即可生成专属的Provider和Hook:
// /i18n/modules/auth/entrance.js import french from "../../french/auth/entrance/i18n"; import english from "../../english/auth/entrance/i18n"; import spanish from "../../spanish/auth/entrance/i18n"; import wolof from "../../wolof/auth/entrance/i18n"; import { createLangContext } from "../../../utils/language/createLangContext"; // 仅需要写当前页面的语言匹配逻辑 const getModuleResource = (lang) => { switch (lang) { case "french": return french; case "english": return english; case "spanish": return spanish; case "wolof": return wolof; default: return french; } }; // 工厂直接生成Provider和Hook export const { useLanguageContext, LanguageProvider } = createLangContext(getModuleResource);
后续页面包裹Provider、子组件调用Hook的逻辑和你之前的实现完全一致,无需调整。
内容的提问来源于stack exchange,提问作者Kcyr
相关产品推荐
相关产品推荐

