【问题标题】:How can I use async and await in react render如何在反应渲染中使用异步和等待
【发布时间】:2021-04-22 03:59:03
【问题描述】:

我正在开发一个 react-native 应用程序,我想要多语言支持。我还写了 languageHelper 以便于管理。

languageHelper.js

import AsyncStorage from '@react-native-async-storage/async-storage';

export const Translator = async (key) => {
    try {
        const langCode = await AsyncStorage.getItem('@lang_code')
        return I18n.t(key, { locale: langCode ?? 'en' })
    } catch (e) {
        return I18n.t(key)
    }
}

login.js

render() {
        return (
            <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
                <KeyboardAvoidingView behavior={'height'} style={styles.container}>
                    <ScrollView>
                        <ImageBackground source={require('../Sources/LoginBg.jpg')} style={styles.backgroundImage}>
                            <Layout style={styles.header}>
                                <Text category='h1' status='primary'> {Translator('Login_hello')}</Text>
                                <Text category='h6' status='primary'> {Translator('Login_signInMessage')}</Text>
                            </Layout> 

我遇到的错误

Error: Objects are not valid as a React child (found: object with keys {_U, _V, _W, _X}). If you meant to render a collection of children, use an array instead.

但是由于 Translator 是一个异步函数,所以我不能在渲染中使用。 (我尝试异步渲染)。

我该如何解决这个问题?感谢您的帮助。

【问题讨论】:

  • 在componentWillMount请求翻译并将结果保存在状态中,然后渲染这些状态变量。

标签: reactjs react-native async-await


【解决方案1】:

这似乎是一个不太高效的代码,但如果你想让它工作,你可以在你的翻译工作时返回一个空字符串,像这样:

import AsyncStorage from '@react-native-async-storage/async-storage';

export const Translator = React.memo(({key}) => {
    const [text, setText] = useState('')

    React.useEffect(() => {
       translate()
    }, [key])

    const translate = async () => {
        try {
           const langCode = await AsyncStorage.getItem('@lang_code')
           setText(I18n.t(key, { locale: langCode ?? 'en' }))
        } catch (e) {
           setText(I18n.t(key))
        }
    }
    
    return (
        <Text>{text}</Text>
    )
})

你可以在你的代码中这样使用它(使用你的例子):

render() {
        return (
            <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
                <KeyboardAvoidingView behavior={'height'} style={styles.container}>
                    <ScrollView>
                        <ImageBackground source={require('../Sources/LoginBg.jpg')} style={styles.backgroundImage}>
                            <Layout style={styles.header}>
                                <Translator('Login_hello')} />
                                <Translator('Login_signInMessage')} />
                            </Layout> 

您还可以让您的翻译人员接受样式道具来自定义最终结果。在那里使用memo 也很重要,这样您的翻译组件上就不会有额外的渲染,因为它总是从异步请求。

其他解决方案

我真正推荐的解决方案是创建一个翻译提供程序并在那里全局配置 i18n,这样您就只有一个存储请求,并且您的翻译组件的加载成本会非常低。

您的项目取得成功。

【讨论】:

  • 它有效。非常感谢。我还将审查您建议的其他解决方案。
猜你喜欢
  • 1970-01-01
  • 2019-05-18
  • 2020-06-14
  • 2022-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多