[英]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.