Skip to content

Commit

Permalink
Merge pull request #7 from theliturgists/redux-start
Browse files Browse the repository at this point in the history
Wire up redux and react-navigation
  • Loading branch information
brettdh committed Jan 7, 2018
2 parents 4e85e96 + de76458 commit 2ca8116
Show file tree
Hide file tree
Showing 16 changed files with 302 additions and 25 deletions.
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"extends": "airbnb",
"rules": {
// Apprently react-native doesn't like .jsx files
"react/jsx-filename-extension": [2, { "extensions": [".js"] }]
"react/jsx-filename-extension": ["error", { "extensions": [".js"] }],
"import/prefer-default-export": "off"
}
}
4 changes: 2 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AppRegistry } from 'react-native';
import App from './src/App';
import Root from './src/Root';

AppRegistry.registerComponent('app', () => App);
AppRegistry.registerComponent('app', () => Root);
9 changes: 7 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,13 @@
"flow": "flow"
},
"dependencies": {
"prop-types": "^15.6.0",
"react": "16.0.0-beta.5",
"react-native": "0.49.3"
"react-native": "0.49.3",
"react-navigation": "^1.0.0-beta.22",
"react-redux": "^5.0.6",
"redux": "^3.7.2",
"redux-actions": "^2.2.1"
},
"devDependencies": {
"babel-jest": "21.2.0",
Expand All @@ -28,8 +33,8 @@
"jest": {
"preset": "react-native"
},
"comment": "flow is disabled in pre-commit because react-navigation breaks it",
"pre-commit": [
"flow",
"lint",
"test"
]
Expand Down
14 changes: 0 additions & 14 deletions src/App.js

This file was deleted.

13 changes: 13 additions & 0 deletions src/Root.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react';
import { Provider } from 'react-redux';

import AppNavigator from './navigators/AppNavigator';
import configureStore from './state/store';

const Root = () => (
<Provider store={configureStore()}>
<AppNavigator />
</Provider>
);

export default Root;
63 changes: 63 additions & 0 deletions src/navigators/AppNavigator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Bootstrapped from the example app at https://reactnavigation.org/docs/guides/redux

import React, { Component } from 'react';
import PropTypes from 'prop-types';

import { BackHandler } from 'react-native';
import { connect } from 'react-redux';
import { TabNavigator, addNavigationHelpers, NavigationActions } from 'react-navigation';

import LoginScreen from '../screens/LoginScreen';
import MainNavigator from './MainNavigator';

export const RawNavigator = TabNavigator({
Login: { screen: LoginScreen },
Main: { screen: MainNavigator },
}, {
navigationOptions: {
tabBarVisible: false,
},
});

class AppNavigator extends Component {
componentDidMount() {
BackHandler.addEventListener('hardwareBackPress', this.onBackPress);
}

componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress', this.onBackPress);
}

onBackPress() {
const { dispatch, nav } = this.props;
if (nav.index === 0) {
return false;
}
dispatch(NavigationActions.back());
return true;
}

render() {
const { dispatch, nav } = this.props;
const navigation = addNavigationHelpers({
dispatch,
state: nav,
});

return <RawNavigator navigation={navigation} />;
}
}

AppNavigator.propTypes = {
dispatch: PropTypes.func.isRequired,

nav: PropTypes.shape({}).isRequired,
};

function mapStateToProps(state) {
return {
nav: state.navigation,
};
}

export default connect(mapStateToProps)(AppNavigator);
9 changes: 9 additions & 0 deletions src/navigators/MainNavigator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { TabNavigator } from 'react-navigation';

import HomeScreen from '../screens/HomeScreen';
import PodcastsScreen from '../screens/PodcastsScreen';

export default TabNavigator({
Home: { screen: HomeScreen },
Podcasts: { screen: PodcastsScreen },
});
25 changes: 25 additions & 0 deletions src/screens/HomeScreen.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Text, View, Button } from 'react-native';

import * as navActions from '../state/ducks/navigation/actions';

const HomeScreen = ({ navigation }) => (
<View>
<Text>
Placeholder home screen
</Text>
<Button
onPress={() => navigation.dispatch(navActions.logout())}
title="Log out"
/>
</View>
);

HomeScreen.propTypes = {
navigation: PropTypes.shape({
dispatch: PropTypes.func.isRequired,
}).isRequired,
};

export default HomeScreen;
25 changes: 25 additions & 0 deletions src/screens/LoginScreen.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Text, View, Button } from 'react-native';

import * as navActions from '../state/ducks/navigation/actions';

const LoginScreen = ({ navigation }) => (
<View>
<Text>
Placeholder login screen
</Text>
<Button
onPress={() => navigation.dispatch(navActions.login())}
title="Log in"
/>
</View>
);

LoginScreen.propTypes = {
navigation: PropTypes.shape({
dispatch: PropTypes.func.isRequired,
}).isRequired,
};

export default LoginScreen;
25 changes: 25 additions & 0 deletions src/screens/PodcastsScreen.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Text, View, Button } from 'react-native';

import * as navActions from '../state/ducks/navigation/actions';

const PodcastsScreen = ({ navigation }) => (
<View>
<Text>
Placeholder podcasts screen
</Text>
<Button
onPress={() => navigation.dispatch(navActions.logout())}
title="Log out"
/>
</View>
);

PodcastsScreen.propTypes = {
navigation: PropTypes.shape({
dispatch: PropTypes.func.isRequired,
}).isRequired,
};

export default PodcastsScreen;
1 change: 1 addition & 0 deletions src/state/ducks/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as navigation } from './navigation';
4 changes: 4 additions & 0 deletions src/state/ducks/navigation/actions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { NavigationActions } from 'react-navigation';

export const login = () => NavigationActions.navigate({ routeName: 'Main' });
export const logout = () => NavigationActions.navigate({ routeName: 'Login' });
1 change: 1 addition & 0 deletions src/state/ducks/navigation/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './reducer';
11 changes: 11 additions & 0 deletions src/state/ducks/navigation/reducer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Bootstrapped from the example app at https://reactnavigation.org/docs/guides/redux

import { RawNavigator } from '../../../navigators/AppNavigator';

const initialAction = RawNavigator.router.getActionForPathAndParams('Login');
const initialState = RawNavigator.router.getStateForAction(initialAction);

export default function reducer(state = initialState, action) {
const nextState = RawNavigator.router.getStateForAction(action, state);
return nextState || state;
}
8 changes: 8 additions & 0 deletions src/state/store.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { combineReducers, createStore } from 'redux';

import * as reducers from './ducks';

export default function configureStore() {
const reducer = combineReducers(reducers);
return createStore(reducer);
}

0 comments on commit 2ca8116

Please sign in to comment.