Skip to content

Commit 4f6440e

Browse files
author
Matthieu Napoli
committed
Merge branch 'startup-saga' into 'master'
Startup saga See merge request tcm-projects/react-native-boilerplate!11
2 parents 7a51181 + f74606e commit 4f6440e

File tree

16 files changed

+326
-6
lines changed

16 files changed

+326
-6
lines changed

App/App.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React, { Component } from 'react'
22
import { Provider } from 'react-redux'
33
import { PersistGate } from 'redux-persist/lib/integration/react'
44
import createStore from 'App/Stores'
5-
import ExampleScreen from './Containers/Example/ExampleScreen'
5+
import RootScreen from './Containers/Root/RootScreen'
66

77
const { store, persistor } = createStore()
88

@@ -21,7 +21,7 @@ export default class App extends Component {
2121
* @see https://github.com/rt2zz/redux-persist/blob/master/docs/PersistGate.md
2222
*/}
2323
<PersistGate loading={null} persistor={persistor}>
24-
<ExampleScreen />
24+
<RootScreen />
2525
</PersistGate>
2626
</Provider>
2727
)

App/Containers/Root/RootScreen.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import React, { Component } from 'react'
2+
import { createStackNavigator } from 'react-navigation'
3+
import NavigationService from 'App/Services/NavigationService'
4+
import { View } from 'react-native'
5+
import styles from './RootScreenStyle'
6+
import ExampleScreen from 'App/Containers/Example/ExampleScreen'
7+
import SplashScreen from 'App/Containers/SplashScreen/SplashScreen'
8+
import { connect } from 'react-redux'
9+
import StartupActions from 'App/Stores/Startup/Actions'
10+
11+
/**
12+
* The root screen contains the application's navigation.
13+
*
14+
* @see https://reactnavigation.org/docs/en/hello-react-navigation.html#creating-a-stack-navigator
15+
*/
16+
const AppNav = createStackNavigator(
17+
{
18+
// Create the application routes here (the key is the route name, the value is the target screen)
19+
// See https://reactnavigation.org/docs/en/stack-navigator.html#routeconfigs
20+
SplashScreen: SplashScreen,
21+
MainScreen: ExampleScreen,
22+
},
23+
{
24+
// By default the application will show the splash screen
25+
initialRouteName: 'SplashScreen',
26+
// See https://reactnavigation.org/docs/en/stack-navigator.html#stacknavigatorconfig
27+
headerMode: 'none',
28+
}
29+
)
30+
31+
class RootScreen extends Component {
32+
componentDidMount() {
33+
// Run the startup saga when the application is starting
34+
this.props.startup()
35+
}
36+
37+
render() {
38+
return (
39+
<View style={styles.container}>
40+
<AppNav
41+
// Initialize the NavigationService (see https://reactnavigation.org/docs/en/navigating-without-navigation-prop.html)
42+
ref={(navigatorRef) => {
43+
NavigationService.setTopLevelNavigator(navigatorRef)
44+
}}
45+
/>
46+
</View>
47+
)
48+
}
49+
}
50+
51+
const mapStateToProps = (state) => ({})
52+
53+
const mapDispatchToProps = (dispatch) => ({
54+
startup: () => dispatch(StartupActions.startup()),
55+
})
56+
57+
export default connect(
58+
mapStateToProps,
59+
mapDispatchToProps
60+
)(RootScreen)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { StyleSheet } from 'react-native'
2+
import ApplicationStyles from 'App/Theme/ApplicationStyles'
3+
4+
export default StyleSheet.create({
5+
container: {
6+
...ApplicationStyles.screen.container,
7+
},
8+
})
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import React from 'react'
2+
import { Text, View } from 'react-native'
3+
import styles from './SplashScreenStyle'
4+
5+
export default class SplashScreen extends React.Component {
6+
render() {
7+
return (
8+
<View style={styles.container}>
9+
<View style={styles.logo}>
10+
<Text>LOGO</Text>
11+
</View>
12+
</View>
13+
)
14+
}
15+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { StyleSheet } from 'react-native'
2+
import Colors from 'App/Theme/Colors'
3+
import ApplicationStyles from 'App/Theme/ApplicationStyles'
4+
5+
export default StyleSheet.create({
6+
container: {
7+
...ApplicationStyles.screen.container,
8+
display: 'flex',
9+
justifyContent: 'center',
10+
alignItems: 'center',
11+
backgroundColor: Colors.primary,
12+
},
13+
logo: {
14+
display: 'flex',
15+
justifyContent: 'center',
16+
alignItems: 'center',
17+
height: 70,
18+
width: 70,
19+
backgroundColor: 'white',
20+
},
21+
})

App/Sagas/ExampleSaga.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { put, call } from 'redux-saga/effects'
22
import ExampleActions from 'App/Stores/Example/Actions'
3-
import { WeatherService } from 'App/Service/WeatherService'
3+
import { WeatherService } from 'App/Services/WeatherService'
44

55
/**
66
* A saga can contain multiple functions.

App/Sagas/StartupSaga.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { put } from 'redux-saga/effects'
2+
import ExampleActions from 'App/Stores/Example/Actions'
3+
import NavigationService from 'App/Services/NavigationService'
4+
5+
/**
6+
* The startup saga is the place to define behavior to execute when the application starts.
7+
*/
8+
export function* startup() {
9+
// Dispatch a redux action using `put()`
10+
// @see https://redux-saga.js.org/docs/basics/DispatchingActions.html
11+
yield put(ExampleActions.fetchTemperature())
12+
13+
// Add more operations you need to do at startup here
14+
// ...
15+
16+
// When those operations are finished we redirect to the main screen
17+
NavigationService.navigateAndReset('MainScreen')
18+
}

App/Sagas/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
import { takeLatest } from 'redux-saga/effects'
22
import { ExampleTypes } from 'App/Stores/Example/Actions'
3+
import { StartupTypes } from 'App/Stores/Startup/Actions'
34
import { fetchTemperature } from './ExampleSaga'
5+
import { startup } from './StartupSaga'
46

57
export default function* root() {
68
yield [
79
/**
810
* @see https://redux-saga.js.org/docs/basics/UsingSagaHelpers.html
911
*/
12+
// Run the startup saga when the application starts
13+
takeLatest(StartupTypes.STARTUP, startup),
1014
// Call `fetchTemperature()` when a `FETCH_TEMPERATURE` action is triggered
1115
takeLatest(ExampleTypes.FETCH_TEMPERATURE, fetchTemperature),
1216
]

App/Service/README.md

Lines changed: 0 additions & 1 deletion
This file was deleted.

App/Services/NavigationService.js

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { NavigationActions, StackActions } from 'react-navigation'
2+
3+
/**
4+
* The navigation is implemented as a service so that it can be used outside of components, for example in sagas.
5+
*
6+
* @see https://reactnavigation.org/docs/en/navigating-without-navigation-prop.html
7+
*/
8+
9+
let navigator
10+
11+
/**
12+
* This function is called when the RootScreen is created to set the navigator instance to use.
13+
*/
14+
function setTopLevelNavigator(navigatorRef) {
15+
navigator = navigatorRef
16+
}
17+
18+
/**
19+
* Call this function when you want to navigate to a specific route.
20+
*
21+
* @param routeName The name of the route to navigate to. Routes are defined in RootScreen using createStackNavigator()
22+
* @param params Route parameters.
23+
*/
24+
function navigate(routeName, params) {
25+
navigator.dispatch(
26+
NavigationActions.navigate({
27+
routeName,
28+
params,
29+
})
30+
)
31+
}
32+
33+
/**
34+
* Call this function when you want to navigate to a specific route AND reset the navigation history.
35+
*
36+
* That means the user cannot go back. This is useful for example to redirect from a splashscreen to
37+
* the main screen: the user should not be able to go back to the splashscreen.
38+
*
39+
* @param routeName The name of the route to navigate to. Routes are defined in RootScreen using createStackNavigator()
40+
* @param params Route parameters.
41+
*/
42+
function navigateAndReset(routeName, params) {
43+
navigator.dispatch(
44+
StackActions.reset({
45+
index: 0,
46+
key: null,
47+
actions: [
48+
NavigationActions.navigate({
49+
routeName,
50+
params,
51+
}),
52+
],
53+
})
54+
)
55+
}
56+
57+
export default {
58+
navigate,
59+
navigateAndReset,
60+
setTopLevelNavigator,
61+
}

0 commit comments

Comments
 (0)