如何在 React Native 中为不同的父组件创建一种上下文模板?

How to create a sort of Context Template for different parents components in react native?

我只想使用 redux 来国际化我的 react 本机应用程序,但为了简洁起见,我将避开与 redux 相关的部分,因为整个应用程序运行得非常好。对于应用程序的每个屏幕组件,我创建一个上下文来包装屏幕组件并传递与屏幕相关的所有字符串

所以我在一个单独的文件中创建了上下文,我将导出为 Language:

import React, { useContext, createContext } from "react";
import { useSelector } from "react-redux";
import { getTranslation } from "../../../redux/reducers/translation/selector/selector";
import {language} from "./Util";

export const Context = createContext();

export const useLanguageContext = () => {
  return useContext(Context);
};

export default function Language({ children }) {
  const translation = useSelector(getTranslation);
  const lang = language(translation.lang);
  return <Context.Provider value={lang}>{children}</Context.Provider>;
}

translation.lang 是从 redux 中获取的当前语言,我将其传递给 language 函数以相应地获取与屏幕相关的字符串。在这种情况下,它将成为入口屏幕。这是 language 函数的逻辑:

import french from "../../../i18n/french/auth/entrance/i18n";
import english from "../../../i18n/english/auth/entrance/i18n";
import spanish from "../../../i18n/spanish/auth/entrance/i18n";
import wolof from "../../../i18n/wolof/auth/entrance/i18n";

export const language = (translation) => {
  switch (translation) {
    case "french":
      return french;
    case "english":
      return english;
    case "spanish":
      return spanish;
    case "wolof":
      return wolof;
    default:
      return french;
  }
};

然后我将 入口 屏幕用这样的上下文包裹起来

import React from "react";
import { View } from "react-native";
import { Slider, Button } from "../../../components/organisms/auth/Entrance";
import Language from "../../../utils/language/context";
import { styles } from "./Style";

export default function Entrance() {
  return (
    <Language>
      <View style={styles.container}>
        <Slider />
        <Button />
      </View>
    </Language>
  );
}

最后,从像 Button 这样的子组件中,我可以检索像这样传递的语言对象

import React from "react";
import { Text, TouchableOpacity } from "react-native";
import { useNavigation } from "@react-navigation/native";
import { useLanguageContext } from "../../../../../../utils/language/context";
import { styles } from "./Style";

export default function Button() {
  const lang = useLanguageContext();
  const navigation = useNavigation();
  return (
    <TouchableOpacity
      style={styles.container}
      onPress={() => {
        navigation.navigate("LoginNavigator");
      }}
    >
      <Text style={styles.text}>{lang.login}</Text>
    </TouchableOpacity>
  );
}

现在所有这些都工作得很好,但主要问题是我将有很多屏幕并且不想重复这个为每个屏幕创建上下文的过程。有没有更简洁的方法来创建一种我可以用于不同屏幕的上下文模板,而不是为每个屏幕创建一个?

如果此实现的目的是将每个屏幕的翻译分开,那么您可以将 属性 传递给上下文提供程序,它只为您想要的屏幕抓取翻译。

一个很酷的提示可以更轻松地导入语言而不是单独导入每一种语言,那就是创建一个索引文件,从一个条目中导出它,例如:

而不是

import french from "../../../i18n/french/auth/entrance/i18n";
import english from "../../../i18n/english/auth/entrance/i18n";
import spanish from "../../../i18n/spanish/auth/entrance/i18n";
import wolof from "../../../i18n/wolof/auth/entrance/i18n";

../../../i18n/french/auth 中创建一个索引文件,像这样导出针对特定屏幕的翻译

export * as entrance from "./entrance/i18n"
export * as login from "./login/i18n"
// etc

然后,从每个语言文件夹中,一个索引文件从一个地方导出相关的翻译

export * from "./auth"
export * from "./home"
// etc

这样就可以像这样访问它,其中屏幕是要为其翻译的屏幕的名称,翻译是语言

import french from "../../../i18n/french"
// other languages
export const language = (screen, translation) => {
  switch (translation) {
    case "french":
      return french[screen];
    // other languages
    default:
      return french[screen];
  }
};

希望对您有所帮助!

我尝试了一些非常简单的东西,没想到它会起作用 现在在 Context 文件中,我将 language 函数作为 props 传递给 Context 将换行的每个屏幕

import React, { useContext, createContext } from "react";
import { useSelector } from "react-redux";
import { getTranslation } from "../../../redux/reducers/translation/selector/selector";

export const Context = createContext();

export const useLanguageContext = () => {
  return useContext(Context);
};

export default function Language({ children, language }) {
  const translation = useSelector(getTranslation);
  const lang = language(translation.lang);
  return <Context.Provider value={lang}>{children}</Context.Provider>;
}

然后在每个 Screen 中,我将导入语言函数并用 Context 包装它,如下所示:

import React from "react";
import { View } from "react-native";
import { Slider, Buttons } from "../../../components/organisms/auth/Entrance";
import Language from "../../../utils/language/context";
import { styles } from "./Style";
import { language } from "./Utils";

export default function Entrance() {
  return (
    <Language language={language}>
      <View style={styles.container}>
        <Slider />
        <Buttons />
      </View>
    </Language>
  );
}

它奏效了。 @Ibrahim 感谢您的回答,我将尝试按照您提到的方式构建翻译文件夹