我正在处理数据初始化的应用程序的初始屏幕。
渴望的结果很简单:
loading indicator
check icon
为了将视图更改为显示loading indicator
到check icon
,我需要更新传递到初始屏幕场景的dataReady
道具,但我不知道不知道如何更新导航状态(即通过导航状态的route
对象将道具传递给场景)。
这是我的尝试(不能按预期工作):
class MainRouter extends React.Component {
componentWillMount() {
// Load data.
this.props.initApp();
}
componentWillReceiveProps(nextProps) {
// initAppReady is set to true 1 second after data loaded.
if (nextProps.initAppReady) {
this.props.handleNavigation({ type: 'PUSH', route: { key: 'home' } });
}
}
renderScene = props => {
switch (props.scene.key) {
case 'scene_splash_screen':
// dataReady is set to true after data loaded.
return (<SplashScreen dataReady={this.props.dataReady} />);
case 'scene_home':
return (<Home />);
default:
return null;
}
}
render() {
return (
<NavigationCardStack
direction={'vertical'}
navigationState={this.props.mainRoutes}
renderScene={this.renderScene}
/>
);
}
}
因此,更改renderScene
时不会调用props.dataReady
方法,因此SplashScreen
场景不会相应更新。
答案 0 :(得分:1)
您应该创建一个新的AppLoader
组件,该组件显示启动屏幕并执行初始数据加载。此外,您应该让initAppReady
函数返回一个承诺,而不是将initApp
作为道具传递给路由器,该承诺会在应用准备就绪时解析,然后AppLoader
可以执行暂停一秒钟,然后导航到家庭场景。
注意:我注意到你把家庭路线推到了堆栈上。我建议你用归位路线替换堆栈。如果您继续操作,那么用户可能会意外导航回您的启动画面,这可能不是您想要的。
这是我的意思的一个例子:
<强> MainRouter.js 强>
class MainRouter extends React.Component {
renderScene = props => {
switch (props.scene.key) {
case 'scene_splash_screen':
return (<AppLoader initApp={this.props.initApp} handleNavigation={this.props.handleNavigation} />);
case 'scene_home':
return (<Home />);
default:
return null;
}
}
render() {
return (
<NavigationCardStack
direction={'vertical'}
navigationState={this.props.mainRoutes}
renderScene={this.renderScene}
/>
);
}
}
<强> AppLoader.js 强>
const AFTER_INIT_DELAY = 1000;
class AppLoader extends React.Component {
static propTypes = {
initApp: PropTypes.func,
handleNavigation: PropTypes.func,
};
constructor(props) {
super(props);
this.state = {
dataReady: false,
};
}
componentWillMount() {
this.props.initApp()
.then(() => {
this.setState({dataReady: true}, this.afterAppInit);
})
.catch(() => {
// Do something if the app init fails
})
}
afterAppInit = () => {
setTimeout(() => {
this.props.handleNavigation({ type: 'REPLACE', route: { key: 'home' } });
}, AFTER_INIT_DELAY);
}
render() {
return (
<SplashSceen dataReady={this.state.dataReady} />
);
}
}