我使用的是react-navigation
,这是我的结构:
根堆栈导航器:
export const Root = StackNavigator({
Index: {
screen: Index,
navigationOptions: ({ navigation }) => ({
}),
},
Cart: {
screen: Cart,
navigationOptions: ({ navigation }) => ({
title: 'Votre panier',
drawerLabel: 'Cart',
drawerIcon: ({ tintColor }) => <Icon theme={{ iconFamily: 'FontAwesome' }} size={26} name="shopping-basket" color={tintColor} />
}),
},
...
我的结构如下:
- StackNavigator(根)
- 抽屉导航器(索引)
- 选项卡导航器
- 我的页面
- MyPage(使用不同数据格式化的同一页面)
所以我的问题是,我在哪里加载数据,初始化我的应用程序?我需要一个叫一次的地方,在其他页面之前叫一次。
我的应用程序中显示的第一个页面是MyPage页面。但正如您所看到的,由于TabNavigator,如果我把函数放在里面,它会被调用很多次。
有些人会在防溅屏上说,但我使用的是主防溅屏组件,我对它没有太多控制
我考虑过我的App.js,在那里我们创建了提供者,但我认为这不是一个好主意?
const MyApp = () => {
//TODO We're loading the data here, I don't know if it's the good decision
ApplicationManager.loadData(store);
SplashScreen.hide();
return (
<Provider store={store}>
<Root/>
</Provider>
);
};
做这件事的好方法是什么?
class MyApp extends Component {
state = {
initialized: false
}
componentWillMount() {
// if this is a promise, otherwise pass a callback to call when it's done
ApplicationManager.loadData(store).then(() => {
this.setState({ initialized: true })
})
}
render() {
const { initialized } = this.state
if (!initialized) {
return <SplashScreen />
}
return (
<Provider store={store} >
<Root />
</Provider>
);
}
}
TabNavigator默认情况下同时渲染/加载其所有子组件,但如果设置属性lazy: true
,则组件将仅在导航时渲染。这意味着您的函数将不会被多次调用。
const Tabs = TabNavigator(
{
MyPage : {
screen: MyPage
},
MyPage2 : {
screen: MyPage,
}
}
},
{
lazy: true
}
);
如果您使用此结构并在MyPage内部调用获取数据,则可以在componentWillReceiveProps
中添加逻辑,该逻辑将检查存储中是否已存在数据和/或在获取新数据之前是否已更改数据。从MyPage调用fetch函数可以在每次访问页面/屏幕时提取新数据,或者在需要时进行"提取刷新"。
你也可以在splashscreen时间提取初始数据,我只是不建议在那个时候提取所有应用程序数据,所有屏幕的数据,因为你可能不需要一次全部提取。你可以做一些类似的事情:
class MyApp extends Component {
state = {
initialized: false
}
componentWillMount() {
// if this is a promise, otherwise pass a callback to call when it's done
ApplicationManager.loadData(store).then(() => {
this.setState({ initialized: true })
})
}
render() {
const { initialized } = this.state
if (!initialized) {
return null
}
return (
<Provider store={store} >
<Root />
</Provider>
);
}
}
class Root extends Component {
componentDidMount() {
SplashScreen.hide();
}
...
}
您应该在App.js
或初始化StackNavigator
的地方执行此操作。如果我是你,我会放一个加载屏幕,一旦数据准备好,它就会被StackNavigator
结构所取代。
我不会在应用程序中这样做,因为你失去了控制。遗憾的是,我没有使用react导航或redux,但我看到TabNavigator有一个tabBarOnPress方法,我会用它来触发加载。您可以根据需要加载每个页面的数据。
https://reactnavigation.org/docs/navigators/tab#tabBarOnPress