Add events support to redux example (#3368)

* Fixing redux

* Fix tab events and test event nested event subscriptions

* Add event support to redux example
This commit is contained in:
Eric Vicenti
2018-01-27 14:12:16 -08:00
committed by Brent Vatne
parent 50a3f8de93
commit dca37627a2
8 changed files with 630 additions and 105 deletions

View File

@@ -45,35 +45,69 @@ MyHomeScreen.navigationOptions = {
),
};
const MyPeopleScreen = ({ navigation }) => (
<MyNavScreen banner="People Tab" navigation={navigation} />
);
class MyPeopleScreen extends React.Component {
static navigationOptions = {
tabBarLabel: 'People',
tabBarIcon: ({ tintColor, focused }) => (
<Ionicons
name={focused ? 'ios-people' : 'ios-people-outline'}
size={26}
style={{ color: tintColor }}
/>
),
};
componentDidMount() {
this._s0 = this.props.navigation.addListener('willFocus', this._onEvent);
this._s1 = this.props.navigation.addListener('didFocus', this._onEvent);
this._s2 = this.props.navigation.addListener('willBlur', this._onEvent);
this._s3 = this.props.navigation.addListener('didBlur', this._onEvent);
}
componentWillUnmount() {
this._s0.remove();
this._s1.remove();
this._s2.remove();
this._s3.remove();
}
_onEvent = a => {
console.log('EVENT ON PEOPLE TAB', a.type, a);
};
render() {
const { navigation } = this.props;
return <MyNavScreen banner="People Tab" navigation={navigation} />;
}
}
MyPeopleScreen.navigationOptions = {
tabBarLabel: 'People',
tabBarIcon: ({ tintColor, focused }) => (
<Ionicons
name={focused ? 'ios-people' : 'ios-people-outline'}
size={26}
style={{ color: tintColor }}
/>
),
};
const MyChatScreen = ({ navigation }) => (
<MyNavScreen banner="Chat Tab" navigation={navigation} />
);
MyChatScreen.navigationOptions = {
tabBarLabel: 'Chat',
tabBarIcon: ({ tintColor, focused }) => (
<Ionicons
name={focused ? 'ios-chatboxes' : 'ios-chatboxes-outline'}
size={26}
style={{ color: tintColor }}
/>
),
};
class MyChatScreen extends React.Component {
static navigationOptions = {
tabBarLabel: 'Chat',
tabBarIcon: ({ tintColor, focused }) => (
<Ionicons
name={focused ? 'ios-chatboxes' : 'ios-chatboxes-outline'}
size={26}
style={{ color: tintColor }}
/>
),
};
componentDidMount() {
this._s0 = this.props.navigation.addListener('willFocus', this._onEvent);
this._s1 = this.props.navigation.addListener('didFocus', this._onEvent);
this._s2 = this.props.navigation.addListener('willBlur', this._onEvent);
this._s3 = this.props.navigation.addListener('didBlur', this._onEvent);
}
componentWillUnmount() {
this._s0.remove();
this._s1.remove();
this._s2.remove();
this._s3.remove();
}
_onEvent = a => {
console.log('EVENT ON CHAT TAB', a.type, a);
};
render() {
const { navigation } = this.props;
return <MyNavScreen banner="Chat Tab" navigation={navigation} />;
}
}
const MySettingsScreen = ({ navigation }) => (
<MyNavScreen banner="Settings Tab" navigation={navigation} />
@@ -128,10 +162,10 @@ class SimpleTabsContainer extends React.Component<SimpleTabsContainerProps> {
_s3: EventListener;
componentDidMount() {
this._s0 = this.props.navigation.addListener('willFocus', this._onWF);
this._s1 = this.props.navigation.addListener('didFocus', this._onDF);
this._s2 = this.props.navigation.addListener('willBlur', this._onWB);
this._s3 = this.props.navigation.addListener('didBlur', this._onDB);
this._s0 = this.props.navigation.addListener('willFocus', this._onAction);
this._s1 = this.props.navigation.addListener('didFocus', this._onAction);
this._s2 = this.props.navigation.addListener('willBlur', this._onAction);
this._s3 = this.props.navigation.addListener('didBlur', this._onAction);
}
componentWillUnmount() {
this._s0.remove();
@@ -139,17 +173,8 @@ class SimpleTabsContainer extends React.Component<SimpleTabsContainerProps> {
this._s2.remove();
this._s3.remove();
}
_onWF = a => {
console.log('_onWillFocus tabsExample ', a);
};
_onDF = a => {
console.log('_onDidFocus tabsExample ', a);
};
_onWB = a => {
console.log('_onWillBlur tabsExample ', a);
};
_onDB = a => {
console.log('_onDidBlur tabsExample ', a);
_onAction = a => {
console.log('TABS EVENT', a.type, a);
};
render() {
return <SimpleTabs navigation={this.props.navigation} />;

View File

@@ -12,13 +12,10 @@
"icon": "./assets/icons/react-navigation.png",
"hideExponentText": false
},
"sdkVersion": "23.0.0",
"sdkVersion": "24.0.0",
"entryPoint": "./node_modules/react-native-scripts/build/bin/crna-entry.js",
"packagerOpts": {
"assetExts": [
"ttf",
"mp4"
]
"assetExts": ["ttf", "mp4"]
},
"ios": {
"supportsTablet": true

View File

@@ -21,10 +21,10 @@
]
},
"dependencies": {
"expo": "^23.0.0",
"expo": "^24.0.2",
"prop-types": "^15.5.10",
"react": "16.0.0",
"react-native": "^0.50.3",
"react-native": "^0.51.0",
"react-redux": "^5.0.6",
"redux": "^3.7.2",
"react-navigation": "link:../.."

View File

@@ -13,17 +13,51 @@ export const AppNavigator = StackNavigator({
Profile: { screen: ProfileScreen },
});
const AppWithNavigationState = ({ dispatch, nav }) => (
<AppNavigator navigation={addNavigationHelpers({ dispatch, state: nav })} />
);
class AppWithNavigationState extends React.Component {
static propTypes = {
dispatch: PropTypes.func.isRequired,
nav: PropTypes.object.isRequired,
};
AppWithNavigationState.propTypes = {
dispatch: PropTypes.func.isRequired,
nav: PropTypes.object.isRequired,
};
_actionEventSubscribers = new Set();
_addListener = (eventName, handler) => {
eventName === 'action' && this._actionEventSubscribers.add(handler);
return {
remove: () => {
this._actionEventSubscribers.delete(handler);
},
};
};
componentDidUpdate(lastProps) {
const lastState = lastProps.nav;
this._actionEventSubscribers.forEach(subscriber => {
subscriber({
lastState: lastProps.nav,
state: this.props.nav,
action: this.props.lastAction,
});
});
}
render() {
const { dispatch, nav } = this.props;
return (
<AppNavigator
navigation={addNavigationHelpers({
dispatch,
state: nav,
addListener: this._addListener,
})}
/>
);
}
}
const mapStateToProps = state => ({
nav: state.nav,
lastAction: state.lastAction,
});
export default connect(mapStateToProps)(AppWithNavigationState);

View File

@@ -36,6 +36,10 @@ function nav(state = initialNavState, action) {
return nextState || state;
}
function lastAction(state = null, action) {
return action;
}
const initialAuthState = { isLoggedIn: false };
function auth(state = initialAuthState, action) {
@@ -50,6 +54,7 @@ function auth(state = initialAuthState, action) {
}
const AppReducer = combineReducers({
lastAction,
nav,
auth,
});

View File

@@ -57,7 +57,7 @@
dependencies:
cross-spawn "^5.1.0"
"@expo/vector-icons@^6.2.0":
"@expo/vector-icons@^6.2.2":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@expo/vector-icons/-/vector-icons-6.2.2.tgz#441edb58a52c0f4e5b4aba1e6f8da1e87cea7e11"
dependencies:
@@ -801,7 +801,7 @@ babel-plugin-transform-es3-property-literals@^6.8.0:
dependencies:
babel-runtime "^6.22.0"
babel-plugin-transform-exponentiation-operator@^6.24.1:
babel-plugin-transform-exponentiation-operator@^6.24.1, babel-plugin-transform-exponentiation-operator@^6.5.0:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e"
dependencies:
@@ -1994,11 +1994,11 @@ expect@^21.2.1:
jest-message-util "^21.2.1"
jest-regex-util "^21.2.0"
expo@^23.0.0:
version "23.0.6"
resolved "https://registry.yarnpkg.com/expo/-/expo-23.0.6.tgz#8cb2c3992b385eb5866cc91f25f159420258d19a"
expo@^24.0.2:
version "24.0.2"
resolved "https://registry.yarnpkg.com/expo/-/expo-24.0.2.tgz#3ff9784afd9efbb8eb739289aa53290ddf31a5a5"
dependencies:
"@expo/vector-icons" "^6.2.0"
"@expo/vector-icons" "^6.2.2"
babel-preset-expo "^4.0.0"
fbemitter "^2.1.1"
invariant "^2.2.2"
@@ -3768,7 +3768,7 @@ methods@^1.1.1, methods@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
metro-bundler@^0.20.1:
metro-bundler@^0.20.0:
version "0.20.3"
resolved "https://registry.yarnpkg.com/metro-bundler/-/metro-bundler-0.20.3.tgz#0ded01b64e8963117017b106f75b83cfc34f3656"
dependencies:
@@ -4717,9 +4717,9 @@ react-native-vector-icons@4.4.2:
prop-types "^15.5.10"
yargs "^8.0.2"
react-native@^0.50.3:
version "0.50.4"
resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.50.4.tgz#194f5da4939087b3acee712a503475f4942dca7e"
react-native@^0.51.0:
version "0.51.0"
resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.51.0.tgz#fe25934b3030fd323f3ca1a70f034133465955ed"
dependencies:
absolute-path "^0.0.0"
art "^0.10.0"
@@ -4727,6 +4727,7 @@ react-native@^0.50.3:
babel-plugin-syntax-trailing-function-commas "^6.20.0"
babel-plugin-transform-async-to-generator "6.16.0"
babel-plugin-transform-class-properties "^6.18.0"
babel-plugin-transform-exponentiation-operator "^6.5.0"
babel-plugin-transform-flow-strip-types "^6.21.0"
babel-plugin-transform-object-rest-spread "^6.20.2"
babel-register "^6.24.1"
@@ -4747,7 +4748,7 @@ react-native@^0.50.3:
graceful-fs "^4.1.3"
inquirer "^3.0.6"
lodash "^4.16.6"
metro-bundler "^0.20.1"
metro-bundler "^0.20.0"
mime "^1.3.4"
minimist "^1.2.0"
mkdirp "^0.5.1"
@@ -4763,7 +4764,7 @@ react-native@^0.50.3:
react-clone-referenced-element "^1.0.1"
react-devtools-core "^2.5.0"
react-timer-mixin "^0.13.2"
regenerator-runtime "^0.9.5"
regenerator-runtime "^0.11.0"
rimraf "^2.5.4"
semver "^5.0.3"
shell-quote "1.6.1"
@@ -4775,15 +4776,8 @@ react-native@^0.50.3:
yargs "^9.0.0"
"react-navigation@link:../..":
version "1.0.0-beta.27"
dependencies:
babel-plugin-transform-define "^1.3.0"
clamp "^1.0.1"
hoist-non-react-statics "^2.2.0"
path-to-regexp "^1.7.0"
prop-types "^15.5.10"
react-native-drawer-layout-polyfill "^1.3.2"
react-native-tab-view "^0.0.74"
version "0.0.0"
uid ""
react-proxy@^1.1.7:
version "1.1.8"
@@ -4924,10 +4918,6 @@ regenerator-runtime@^0.11.0:
version "0.11.1"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
regenerator-runtime@^0.9.5:
version "0.9.6"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.9.6.tgz#d33eb95d0d2001a4be39659707c51b0cb71ce029"
regenerator-transform@^0.10.0:
version "0.10.1"
resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd"