【问题标题】:How to export object based on conditions in react-native?如何根据 react-native 中的条件导出对象?
【发布时间】:2020-03-18 22:58:59
【问题描述】:

我想导出一个对象based on conditions,例如首先我检查一些存储在“AsyncStorage”中的语言,然后根据语言返回一个特定的object

文件lang.js

import AsyncStorage from '@react-native-community/async-storage';
let exportingLang = {};

AsyncStorage.getItem('@lang').then(language=> {
    if(language){
        if(language === "hindi") exportingLang = {
           name: 'a hindi name'
        };
        else if(language === "panjabi") exportingLang = {
           name: 'a panjabi name'
        };
        else exportingLang = {
           name: 'a english name'
        };;
    }
});

export const Lang = exportingLang;

文件post.js

import {Lang} from 'lang';

export default Post = props => {

    return (
        <Text>{Lang.name}</Text>
    );
}

但是上面的代码不起作用。

【问题讨论】:

  • 你肯定需要提供更多关于你在哪里运行那段代码的信息,等等。仅仅靠它自己,那段代码永远不会工作。
  • @AfrazHussain,我已经编辑了我的问题,请看一下
  • 谢谢,您似乎希望将 JavaScript 承诺的响应放入您的渲染中。让我为你想一个简单的答案。
  • 如果下面的答案已经解决,请选择一个答案。
  • 请查看我回答中的最后一条评论。它有一个链接向您展示如何在第一次渲染之前使用UNSAFE_componentWillMount() 来获取您的价值。

标签: javascript react-native es6-promise


【解决方案1】:

这里首先要注意的是getItem根据@​​987654321@返回一个JavaScriptPromise。使用 JavaScript 的工作方式,如果没有 resolvingrejecting Promise,我们无法从 Promise 中获取值并导出它们,更多关于 here 的内容。用你的例子来解释它,你可以给exportingLang赋值,但它几乎肯定会返回你初始化它的初始空对象{},因为Promise赋值是异步发生的,也就是说,它需要等待让存储系统找到 @lang 键,然后返回它的值,这可能需要一段时间(因此需要 Promise)。

如果拥有lang.js 文件的目的是避免一遍又一遍地键入 if 语句,那没关系(否则我只会在需要值的组件中使用一次getItem Promise) .我首先要确保我们将 Promise 返回的结果导出如下:

lang.js

export default AsyncStorage.getItem('@lang').then(language => {
  let exportingLang = {name: 'default'};
  if (language) {
    if (language === 'hindi')
      exportingLang = {
        name: 'a hindi name',
      };
    else if (language === 'panjabi')
      exportingLang = {
        name: 'a panjabi name',
      };
    else
      exportingLang = {
        name: 'a english name',
      };
  }
  return exportingLang;
});

这反过来又会给我另一个 Promise 作为导出。

其次,您不能将 Promise 中的值直接用于 React 渲染方法。您需要使用useStateuseEffect 将其分配给一个状态。你可以阅读更多关于here的内容。

为简单起见,我在Component 中使用如下:

import langPromise from './lang';

export default class App extends Component {
  state = {
    lang: { name: '' },
  };

  async componentDidMount() {
    const lang = await langPromise.then(lang => this.setState({ lang }));
  }

  render() {
    return (
      <View>
        <Text>{this.state.lang.name}</Text>
      </View>
    );
  }
}

如果您有任何其他问题,请告诉我。

【讨论】:

  • 我还在:snack.expo.io/rySQiEgIU 为您创建了一个工作零食。请注意,这可能有旧版本的 AsyncStorage,但想法仍然相同。
  • 非常感谢,但我实际上需要在渲染之前而不是渲染之后的东西,在这里,当你工作时,我可以在渲染后访问我不想要的对象。
  • Afraz 的回答非常优雅——我喜欢。我在下面的回答完成了同样的事情。你是什​​么意思你想“在渲染之前”而不是在渲染之后访问对象?在这两个答案中,组件都会呈现,并且一旦您的 AsyncStorage 函数返回一个值,它就会导致状态更改,从而导致重新呈现。您设想在组件生命周期的哪个阶段需要 AsyncStorage 返回的值?
  • @Muhammad 不幸的是,您不能停止渲染组件并使其等待 Promise 返回值,正如 Seth 在上面的评论中所解释的那样。我还在关于同一问题的回答中链接了一个完美的 SO 问题。 如果你仍然不相信并且你真的必须在渲染之前获得你的价值,那么你可以使用UNSAFE_componentWillMount() 来使用你的异步方法。我绝对不推荐它,但你可以阅读在这个完美的博客中了解更多信息:reactjs.org/blog/2018/03/27/…
【解决方案2】:

为什么不将exportingLang 的值存储在状态中,然后在您的组件中使用它?

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

export default Post = props => {

    const [name, setName] = useState()

    AsyncStorage.getItem('@lang').then(language=> {
        if(language){
            if(language === "hindi") {
               setName('a hindi name')
            } else if(language === "panjabi") {
               setName('a punjabi name')
            } else {
               setName('an english name')
            };
        }
    });


    return (
        <Text>{name}</Text>
    );
}

【讨论】:

  • 谢谢,这发生在渲染之后,但我需要在渲染之前访问对象
猜你喜欢
  • 2018-09-06
  • 1970-01-01
  • 1970-01-01
  • 2021-11-04
  • 2018-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
相关资源
最近更新 更多