我正在做移动应用程序,我遇到了一些问题,我不知道如何解决。
我必须在创建一个屏幕后从API加载一些数据。 我在ComponentDidMount
方法中执行此操作,该方法是Async
,因此我可以使用Await
关键字。 然后,我设置状态,这样加载器组件(它只是模态显示文本)就会被隐藏,屏幕会用来自API的数据重新呈现。 这在Android设备上运行良好。 但是在iOS(iPhone X)上运行这段代码是行不通的。 调用somescreen.js
和loader.js
的呈现方法,并且loader.js
呈现方法返回null(与控制台检查),但iPhone上的视图没有更新。 加载器模式仍然存在,即使它的render方法返回null。 我做错什么了吗? 调用this.foceUpdate()
也没有帮助。
somescreen.js
import React, {Component} from 'react';
import Loader from 'components/Loader/Loader';
export default class SomeScreen extends Component {
constructor(props) {
super(props);
this.state = {
loading: true,
data: []
};
}
async componentDidMount() {
const data = await this.loadData();
this.setState({loading: false, data: data})
}
async loadData() {
//fetch and return data from API
}
render() {
return (
<SafeAreaView style={{flex: 1}}>
<Loader loading={this.state.loading}/>
//other rendering...
</SafeAreaView>
);
}
}
loader.js
import React, {Component} from 'react';
import {Modal, Text, View} from 'react-native';
export default class Loader extends Component {
static defaultProps = {
loading: false
};
render() {
if (this.props.loading !== true) {
return null;
}
return(
<Modal
transparent={false}
animationType={'none'}
visible={true}>
<View style={{backgroundColor: "white", flex: 1, justifyContent: "center"}}>
<Text>Loading data...</Text>
</View>
</Modal>
)
}
}
我不知道为什么您会看到iOS和Android之间的区别,但我认为您可以尝试简化loader
组件的呈现方法。 这样可以避免使用2个return
调用。
import React, {Component, Fragment} from 'react';
render() {
return (
<Fragment>
{this.props.loading ? null : {
<Modal
transparent={false}
animationType={'none'}
visible={this.props.loading}>
<View style={{backgroundColor: "white", flex: 1, justifyContent: "center"}}>
<Text>Loading data...</Text>
</View>
</Modal>
}
</Fragment>
)
}
上面的代码检查loading
道具并加载modal
组件,或者什么都不加载。 我还将this.props.loading
道具作为一个值添加到您的模式的visible
道具中。 我想那个可能已经不见了。
我终于找到答案了。 这是因为即使我将animationtype
设置为none
,在iOS模式上也有打开动画。 并且如果我将loading
更改为false
,则在此动画被钓鱼之前,模式仍然是打开的。 动画大约需要550毫秒,我的API调用大约需要200毫秒。
loader.js
import React, {Component} from 'react';
import {Modal, Text, View} from 'react-native';
export default class Loader extends Component {
static defaultProps = {
loading: false
};
constructor(props) {
super(props);
this.state = {
loading: props.loading
};
}
componentWillReceiveProps(nextProps, nextContext) {
if (this.state.loading === true && nextProps.loading === false) {
setTimeout(() => {
this.setState({loading: false});
}, 600);
}
if (this.state.loading === false && nextProps.loading === true) {
this.setState({loading: true});
}
}
render() {
if (this.state.loading !== true) {
return null;
}
return(
<Modal
transparent={false}
animationType={'none'}
visible={this.state.loading}>
<View style={{backgroundColor: "white", flex: 1, justifyContent: "center"}}>
<Text>Loading data...</Text>
</View>
</Modal>
)
}
}
基本上,在我的解决方案中,我确保modal以600毫秒的延迟关闭,这样它就有时间完成它的弹出动画。