使用 promise 时不渲染 returns
Render returns nothing when using promise
我正在尝试实现我的呈现函数,以便它等到我完成从 Web 抓取数据(如果 AsyncStorage 没有)或从 AsyncStorage 获取它,但我正在努力实现承诺它的方面:
render() {
let pic = {
uri: 'https://i.imgur.com/G19Jnuj.jpg'
};
this.renderAttributes()
.then((response) => {
console.log("finished val: " + this.state.name);
console.log("finished response: " + response);
return (
<View style={shared.basicView}>
<Image source={pic} style ={styles.circleImage}/>
<Text style={styles.infoText}>{this.state.name}</Text>
<Text style={styles.titleText}>Bio</Text>
<Text style={styles.infoText}>blah blah</Text>
<Text style={styles.titleText}>Email</Text>
<Text style={styles.infoText}>blah blah</Text>
<Text style={styles.titleText}
onPress={() => this.props.navigation.navigate('Repositories')}>
Public Repos Count</Text>
<Text style={styles.infoText}>3</Text>
<Text style={styles.titleText}
onPress={() => this.props.navigation.navigate('Followers')}>
Follower Count</Text>
<Text style={styles.infoText}>0</Text>
<Text style={styles.titleText}
onPress={() => this.props.navigation.navigate('Following')}>
Following Count</Text>
<Text style={styles.infoText}>0</Text>
<Text style={styles.titleText}>Profile Created</Text>
<Text style={styles.infoText}>November 2015</Text>
</View>
)
})
.catch((error) => {
console.log("Profile creation failed: " + error);
return(null);
})
}
class 的其余部分和 renderAttributes 函数定义如下:
class ProfileScreen extends Component {
state: any;
constructor(props) {
super(props);
this.state = {
name: '',
bio: '',
email: '',
repoCount: '',
followerCount: '',
followingCount: '',
profileCreated: ''
};
this.renderAttributes = this.renderAttributes.bind(this);
}
async renderAttributes() {
console.log("inside ga");
let jsonData=null;
try {
axios.get('https://api.github.com/users/dummy')
.then(async (response) => {
console.log("Response: " + JSON.stringify(response));
jsonData=response;
console.log("jsonData: " + JSON.stringify(jsonData));
const nameVal = await AsyncStorage.getItem('name');
if(nameVal !== null) {
console.log("name val: " + nameVal);
this.setState({name: nameVal});
}
else {
try {
await AsyncStorage.setItem('name', jsonData.data.name);
}
catch (error) {
console.log("Set name error: " + error);
}
if(jsonData.data.name == null) {
this.setState({name: 'n/a'});
}
else {
console.log("name: " + jsonData.data.name);
this.setState({name: jsonData.data.name});
}
}
const bio = await AsyncStorage.getItem('bio');
if(bio !== null) {
this.setState({bio: bio});
}
else {
try {
await AsyncStorage.setItem('bio', jsonData.data.bio);
}
catch (error) {
console.log(error);
}
if(jsonData.data.bio == null) {
this.setState({bio: 'n/a'});
}
else {
this.setState({bio: jsonData.data.bio});
}
}
// etc for each attribute in state
})
.catch((error) => {
console.log('Error fetching: ' + error);
});
}
catch (error) {
console.log('Error creating attributes: ' + error);
}
}
(请原谅我所有的 console.log 陈述)。对我来说,这似乎应该 return null 或 return a View 无论如何,但我不断收到错误 "Invariant Violation: ProfileScreen(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null."
。 None 我的 catch 语句被触发。老实说,我很困惑;我注意到有两件事可能是罪魁祸首:1.我的IDE突出显示this.state.name是一个未解析的变量名,2.我没有在[=14=中明确定义一个承诺] (我应该这样做吗?)。此外,仅基于 print 语句,this.renderAttributes().then(response)
中的内容似乎在 axios.get.then()
之前打印;不确定那是否是一条红鲱鱼。有什么建议吗?
这里的问题是您试图在 render() 函数中解析一个 promise,而 promise 本身是异步的,并且您没有 return 隐含地 [=21] =]未定义。
渲染函数应该是纯净的,没有任何副作用。
您应该将用于获取数据的异步逻辑放在反应生命周期挂钩之一中,例如 componentWillMount()
或 componentDidMount()
其实最好的地方as stated by docs,就是componentDidMount
您应该在第一个 运行 处提供一个 'loading screen'(如空字段 and/or 微调器),并在检索数据(全部在 componentDidMount 中完成)和状态集时显示它
componentWillMount:
Avoid introducing any side-effects or subscriptions in this method.
For those use cases, use componentDidMount() instead.
componentDidMount:
componentDidMount() is invoked immediately after a component is
mounted. Initialization that requires DOM nodes should go here. If you
need to load data from a remote endpoint, this is a good place to
instantiate the network request.
我正在尝试实现我的呈现函数,以便它等到我完成从 Web 抓取数据(如果 AsyncStorage 没有)或从 AsyncStorage 获取它,但我正在努力实现承诺它的方面:
render() {
let pic = {
uri: 'https://i.imgur.com/G19Jnuj.jpg'
};
this.renderAttributes()
.then((response) => {
console.log("finished val: " + this.state.name);
console.log("finished response: " + response);
return (
<View style={shared.basicView}>
<Image source={pic} style ={styles.circleImage}/>
<Text style={styles.infoText}>{this.state.name}</Text>
<Text style={styles.titleText}>Bio</Text>
<Text style={styles.infoText}>blah blah</Text>
<Text style={styles.titleText}>Email</Text>
<Text style={styles.infoText}>blah blah</Text>
<Text style={styles.titleText}
onPress={() => this.props.navigation.navigate('Repositories')}>
Public Repos Count</Text>
<Text style={styles.infoText}>3</Text>
<Text style={styles.titleText}
onPress={() => this.props.navigation.navigate('Followers')}>
Follower Count</Text>
<Text style={styles.infoText}>0</Text>
<Text style={styles.titleText}
onPress={() => this.props.navigation.navigate('Following')}>
Following Count</Text>
<Text style={styles.infoText}>0</Text>
<Text style={styles.titleText}>Profile Created</Text>
<Text style={styles.infoText}>November 2015</Text>
</View>
)
})
.catch((error) => {
console.log("Profile creation failed: " + error);
return(null);
})
}
class 的其余部分和 renderAttributes 函数定义如下:
class ProfileScreen extends Component {
state: any;
constructor(props) {
super(props);
this.state = {
name: '',
bio: '',
email: '',
repoCount: '',
followerCount: '',
followingCount: '',
profileCreated: ''
};
this.renderAttributes = this.renderAttributes.bind(this);
}
async renderAttributes() {
console.log("inside ga");
let jsonData=null;
try {
axios.get('https://api.github.com/users/dummy')
.then(async (response) => {
console.log("Response: " + JSON.stringify(response));
jsonData=response;
console.log("jsonData: " + JSON.stringify(jsonData));
const nameVal = await AsyncStorage.getItem('name');
if(nameVal !== null) {
console.log("name val: " + nameVal);
this.setState({name: nameVal});
}
else {
try {
await AsyncStorage.setItem('name', jsonData.data.name);
}
catch (error) {
console.log("Set name error: " + error);
}
if(jsonData.data.name == null) {
this.setState({name: 'n/a'});
}
else {
console.log("name: " + jsonData.data.name);
this.setState({name: jsonData.data.name});
}
}
const bio = await AsyncStorage.getItem('bio');
if(bio !== null) {
this.setState({bio: bio});
}
else {
try {
await AsyncStorage.setItem('bio', jsonData.data.bio);
}
catch (error) {
console.log(error);
}
if(jsonData.data.bio == null) {
this.setState({bio: 'n/a'});
}
else {
this.setState({bio: jsonData.data.bio});
}
}
// etc for each attribute in state
})
.catch((error) => {
console.log('Error fetching: ' + error);
});
}
catch (error) {
console.log('Error creating attributes: ' + error);
}
}
(请原谅我所有的 console.log 陈述)。对我来说,这似乎应该 return null 或 return a View 无论如何,但我不断收到错误 "Invariant Violation: ProfileScreen(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null."
。 None 我的 catch 语句被触发。老实说,我很困惑;我注意到有两件事可能是罪魁祸首:1.我的IDE突出显示this.state.name是一个未解析的变量名,2.我没有在[=14=中明确定义一个承诺] (我应该这样做吗?)。此外,仅基于 print 语句,this.renderAttributes().then(response)
中的内容似乎在 axios.get.then()
之前打印;不确定那是否是一条红鲱鱼。有什么建议吗?
这里的问题是您试图在 render() 函数中解析一个 promise,而 promise 本身是异步的,并且您没有 return 隐含地 [=21] =]未定义。
渲染函数应该是纯净的,没有任何副作用。
您应该将用于获取数据的异步逻辑放在反应生命周期挂钩之一中,例如 componentWillMount()
或 componentDidMount()
其实最好的地方as stated by docs,就是componentDidMount
您应该在第一个 运行 处提供一个 'loading screen'(如空字段 and/or 微调器),并在检索数据(全部在 componentDidMount 中完成)和状态集时显示它
componentWillMount:
Avoid introducing any side-effects or subscriptions in this method. For those use cases, use componentDidMount() instead.
componentDidMount:
componentDidMount() is invoked immediately after a component is mounted. Initialization that requires DOM nodes should go here. If you need to load data from a remote endpoint, this is a good place to instantiate the network request.