简体   繁体   English

在将数据加载到 this.state(即在 componentDidMount 中)之前,如何防止函数运行?

[英]How do I prevent a function from being run before data is loaded into this.state (i.e. in componentDidMount)?

I have a function getRepresentativeName() which uses a piece of data ( this.state.communityData.Representative ) from this.state to index into a database and retrieve a string.我有一个函数getRepresentativeName()它使用来自this.state的一段数据( this.state.communityData.Representative )来索引到数据库并检索一个字符串。 My intent is that when the component mounts, all of the information in this.state , including this.state.communityData.Representative , will be populated and the representative's name will appear in the location set off by {...} .我的意图是,当组件安装时, this.state所有信息,包括this.state.communityData.Representative ,都将被填充,并且代表的名字将出现在由{...}设置的位置。 However, the function runs immediately when the first render is called and does not wait for the component to mount;但是,该函数在调用第一次渲染时立即运行,不会等待组件挂载; as a result, since this.state is not populated yet, the getRepresentativeName function crashes.作为一个结果,因为this.state未填充然而,getRepresentativeName功能崩溃。

I placed a ternary statement to check whether the communityData JSON object has been filled (the logic being that if it is not filled, ie === {}, just return null instead of executing getRepresenativeName()) ;我放了一个三元语句来检查communityData JSON对象是否被填充(逻辑是如果没有填充,即==={},只返回null而不是executing getRepresenativeName()) Interestingly enough, the page crashes regardless (with the same issue: getRepresenativeName() is being called before this.state is populated in componentDidMount() ).有趣的是,网页崩溃不管(有相同的问题: getRepresenativeName()之前被称为this.state中填充componentDidMount()

Can someone explain to me why this is happening, and how I could resolve this situation without adding redundant data to this.state ?有人可以向我解释为什么会发生这种情况,以及如何在不向this.state添加冗余数据的情况下解决这种情况? I'm not sure if this is the way to solve it, but I thought that the problem could be solved if there was a way to make the getRepresentativeName() function wait until componentDidMount() finishes.我不确定这是否是解决它的方法,但我认为如果有一种方法可以让getRepresentativeName()函数等到componentDidMount()完成,则可以解决问题。 Thank you!谢谢!

Note: If I do not call the function and just replace the {...} with {this.state.communityData.Representative} , which fills the element with the Representative ID as opposed to the name, the page renders perfectly.注意:如果我不调用该函数而只是将{...}替换为{ this.state.communityData.Representative} ,这会使用代表 ID 而非名称填充元素,页面呈现完美。 In addition, I tried making getRepresentative name a callback, and that still didn't work (ie the page still crashed when it tried to render).此外,我尝试将getRepresentative name getRepresentative回调,但仍然无效(即页面在尝试呈现时仍然崩溃)。

  async getRepresentativeName() {
    const representativeSnapshot = await database()
      .ref('users')
      .child(this.state.communityData.Representative)
      .child('name')
      .once('value');
    return representativeSnapshot.val();
  };

  render() {
    console.log('starting render');
    return (
      <View style={styles.containerScreen} testID="communityScreen">
        {/*
            This the container that holds the community Image
            and its description,
            */}
        <View style={styles.containerhorizontal}>
          <View style={styles.containervertical}>
            <Image
              source={require('../../sample_images/va10.jpg')}
              style={styles.image}
            />
          </View>
          <View style={styles.containervertical}>
            <Text style={styles.containerhorizontal}>
              Description: {this.state.communityData.Description}
            </Text>
            <Text style={styles.containerhorizontal}>
              Representative: **{this.state.communityData !== {} ?this.getRepresentativeName() : null}**
            </Text>
            ...

The typical pattern here is initialize your state with some kind of loading property.这里的典型模式是使用某种加载属性初始化您的状态。 Then, asynchronously load data based on input from the user interface.然后,根据来自用户界面的输入异步加载数据。 That input could be from the user or it could be from lifecycle events.该输入可能来自用户,也可能来自生命周期事件。 In this case, componentDidMount.在这种情况下,componentDidMount。 Your component should know how to render when loading is true and when data is available.您的组件应该知道如何在加载为真和数据可用时进行渲染。

class MyComponent extends React.Component {
  state = {loading: true, error: null, representative: null}

  componentDidMount() {
    fetchData().then((representative) => {
      this.setState({ loading: false, representative })
    }).catch((error) => {
      this.setState({ loading: false, error: error.message })
    })
  }

  render() {
    return this.state.error 
    ? <span>woops</span>
    : this.state.loading
    ? <span>busy</span>
    : <div>Representative: {this.state.representative.name}</div>
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我无法从 this.state 获取数据 - I can not get data from this.state 我有一个this.state,我需要通过setState传入我的componentDidMount,如何在setState中使用bind(this)? - I have one this.state and i need pass in my componentDidMount with setState, how use bind(this) in setState? 如何在加载数据之前阻止组件呈现? - How can I prevent a component from rendering before data is loaded? 如何使用.done()回调为请求中加载的新数据运行函数? - How do I use the .done() callback to run a function for new data being loaded on request? (语法?)this.state不是函数错误和componentDidMount中的排序 - (syntax?)this.state is not a function error & sorting in componentDidMount 我如何在this.state中使用this.state - How can I use this.state within this.state 如何循环遍历 `this.state` 对象中的数组? - How do I loop though an array in a `this.state` object? 使用 useState 挂钩时如何访问 this.state? - How do I access a this.state when using the useState hook? 如何停止获取我的 this.state 属性之一以停止未定义? - How do I stop from getting one of my this.state properties to stop getting undefined? 如何将我的 componentDidMount function 转换为异步 componentDidMount 类型 - how do I convert my componentDidMount function to async componentDidMount type
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM