我正在使用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(Root)
- DrawerNavigator(索引)
- TabNavigator的
- 我的页面
- MyPage(使用不同数据格式化的同一页面)
- ...
所以我的问题是,我在哪里加载数据,初始化我的应用程序?我需要调用一次,在其他页面之前调用。
我的应用程序中显示的第一页是MyPage页面。但正如你所看到的,由于TabNavigator,如果我将我的函数放入其中,它将被多次调用。
有人会在启动画面中说,但是我使用的是主splashscreen component,而我没有很多控件。
我想到了我们创建提供程序的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>
);
};
这样做的好方法是什么?
答案 0 :(得分:3)
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>
);
}
}
答案 1 :(得分:2)
TabNavigator默认情况下会同时渲染/加载其所有子组件,但如果设置属性lazy: true
组件将仅在您导航时呈现。这意味着您的功能不会被多次调用。
const Tabs = TabNavigator(
{
MyPage : {
screen: MyPage
},
MyPage2 : {
screen: MyPage,
}
}
},
{
lazy: true
}
);
如果您使用此结构并在MyPage内部调用获取数据,则可以在componentWillReceiveProps
中添加逻辑,该逻辑将检查已存储的数据和/或在获取新数据之前是否已更改。从MyPage调用您的提取功能使您能够在每个页面/屏幕访问时提取新数据,或者如果您需要,可以“拉动刷新”。
您还可以在启动画面时间中提取初始数据,我不建议您同时提取所有应用数据,所有屏幕的数据,因为您可能不需要同时使用所有屏幕。你可以这样做:
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();
}
...
}
答案 2 :(得分:0)
您应该在<html>
<head>
<div id="particles-js"></div>
<script src="particles.js"></script>
<title>MYMDB</title>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.13/semantic.css">
<link rel="stylesheet" type="text/css" href="/stylesheets/app.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>
</body>
</html>
或初始化App.js
的位置执行此操作。如果我是你,我会设置一个加载屏幕,一旦数据准备就会被StackNavigator
结构取代。
答案 3 :(得分:0)
我不会在应用程序中执行此操作,因为您失去了控制权。遗憾的是我没有使用react-navigation或redux但是我看到TabNavigator有一个tabBarOnPress方法,我会用它来触发加载。您可以按需加载每个页面数据。
https://reactnavigation.org/docs/navigators/tab#tabBarOnPress