Skip to content

Commit d969f8c

Browse files
committed
Update IconToolbarAndroid to use componentDidUpdate
1 parent 9b8590b commit d969f8c

File tree

2 files changed

+119
-73
lines changed

2 files changed

+119
-73
lines changed

Diff for: Examples/IconExplorer/index.android.js

+33-36
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
11
import React from 'react';
2-
import {
3-
AppRegistry,
4-
BackAndroid,
5-
StyleSheet,
6-
ToolbarAndroid,
7-
View,
8-
} from 'react-native';
2+
import { AppRegistry, BackAndroid, StyleSheet, View } from 'react-native';
93

104
import Ionicons from 'react-native-vector-icons/Ionicons';
115
import { Navigator } from 'react-native-deprecated-custom-components';
@@ -34,35 +28,38 @@ BackAndroid.addEventListener('hardwareBackPress', () => {
3428

3529
const RouteMapper = (route, navigationOperations) => {
3630
navigator = navigationOperations;
37-
if (route.name === 'list') {
38-
return (
39-
<View style={{ flex: 1 }}>
40-
<Ionicons.ToolbarAndroid
41-
style={styles.toolbar}
42-
titleColor="white"
43-
title={route.title}
44-
/>
45-
<IconSetList navigator={navigationOperations} />
46-
</View>
47-
);
48-
} else if (route.name === 'iconSet') {
49-
return (
50-
<View style={{ flex: 1 }}>
51-
<Ionicons.ToolbarAndroid
52-
actions={[]}
53-
navIconName="md-arrow-back"
54-
onIconClicked={navigationOperations.pop}
55-
style={styles.toolbar}
56-
titleColor="white"
57-
title={route.title}
58-
/>
59-
<IconList
60-
style={{ flex: 1 }}
61-
navigator={navigationOperations}
62-
iconSet={route.iconSet}
63-
/>
64-
</View>
65-
);
31+
switch (route.name) {
32+
case 'list':
33+
return (
34+
<View style={{ flex: 1 }}>
35+
<Ionicons.ToolbarAndroid
36+
style={styles.toolbar}
37+
titleColor="white"
38+
title={route.title}
39+
/>
40+
<IconSetList navigator={navigationOperations} />
41+
</View>
42+
);
43+
case 'iconSet':
44+
return (
45+
<View style={{ flex: 1 }}>
46+
<Ionicons.ToolbarAndroid
47+
actions={[]}
48+
navIconName="md-arrow-back"
49+
onIconClicked={navigationOperations.pop}
50+
style={styles.toolbar}
51+
titleColor="white"
52+
title={route.title}
53+
/>
54+
<IconList
55+
style={{ flex: 1 }}
56+
navigator={navigationOperations}
57+
iconSet={route.iconSet}
58+
/>
59+
</View>
60+
);
61+
default:
62+
throw new Error(`Unknown route "${route.name}"`);
6663
}
6764
};
6865

Diff for: lib/toolbar-android.js

+86-37
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,20 @@ import React, { PureComponent } from 'react';
55
import PropTypes from 'prop-types';
66
import { ToolbarAndroid } from './react-native';
77

8+
const ICON_PROP_NAMES = ['iconSize', 'iconColor', 'titleColor'];
9+
const LOGO_ICON_PROP_NAMES = [...ICON_PROP_NAMES, 'logoName'];
10+
const NAV_ICON_PROP_NAMES = [...ICON_PROP_NAMES, 'navIconName'];
11+
const OVERFLOW_ICON_PROP_NAMES = [...ICON_PROP_NAMES, 'overflowIconName'];
12+
const ACTIONS_PROP_NAMES = [...ICON_PROP_NAMES, 'actions'];
13+
14+
const arePropsEqual = keys => (prevProps, nextProps) =>
15+
isEqual(pick(prevProps, keys), pick(nextProps, keys));
16+
17+
const areLogoIconPropsEqual = arePropsEqual(LOGO_ICON_PROP_NAMES);
18+
const areNavIconPropsEqual = arePropsEqual(NAV_ICON_PROP_NAMES);
19+
const areOverflowIconPropsEqual = arePropsEqual(OVERFLOW_ICON_PROP_NAMES);
20+
const areActionPropsEqual = arePropsEqual(ACTIONS_PROP_NAMES);
21+
822
export default function createToolbarAndroidComponent(
923
IconNamePropType,
1024
getImageSource
@@ -26,68 +40,103 @@ export default function createToolbarAndroidComponent(
2640
),
2741
iconSize: PropTypes.number,
2842
iconColor: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
43+
titleColor: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
2944
};
3045

3146
static defaultProps = {
3247
iconSize: 24,
3348
};
3449

35-
componentWillMount() {
36-
this.updateIconSources(this.props);
50+
state = {
51+
logo: undefined,
52+
navIcon: undefined,
53+
overflowIcon: undefined,
54+
actions: undefined,
55+
};
56+
57+
componentDidMount() {
58+
this.updateLogoIconSource();
59+
this.updateNavIconSource();
60+
this.updateOverflowIconSource();
61+
this.updateActionIconSources();
3762
}
3863

39-
componentWillReceiveProps(nextProps) {
40-
const keys = Object.keys(IconToolbarAndroid.propTypes);
41-
if (!isEqual(pick(nextProps, keys), pick(this.props, keys))) {
42-
const stateToEvict = {};
43-
if (!nextProps.logoName) {
44-
stateToEvict.logo = undefined;
45-
}
46-
if (!nextProps.navIconName) {
47-
stateToEvict.navIcon = undefined;
48-
}
49-
if (!nextProps.overflowIconName) {
50-
stateToEvict.overflowIcon = undefined;
51-
}
52-
if (this.state && Object.keys(stateToEvict).length) {
53-
this.setState(stateToEvict, () => this.updateIconSources(nextProps));
54-
} else {
55-
this.updateIconSources(nextProps);
56-
}
64+
componentDidUpdate(prevProps) {
65+
if (!areLogoIconPropsEqual(prevProps, this.props)) {
66+
this.updateLogoIconSource();
67+
}
68+
if (!areNavIconPropsEqual(prevProps, this.props)) {
69+
this.updateNavIconSource();
70+
}
71+
if (!areOverflowIconPropsEqual(prevProps, this.props)) {
72+
this.updateOverflowIconSource();
73+
}
74+
if (!areActionPropsEqual(prevProps, this.props)) {
75+
this.updateActionIconSources();
5776
}
5877
}
5978

60-
updateIconSources(props) {
61-
const size = props.iconSize;
62-
const color = props.iconColor || props.titleColor;
63-
if (props.logoName) {
64-
getImageSource(props.logoName, size, color).then(logo =>
65-
this.setState({ logo })
79+
async updateLogoIconSource() {
80+
const { logoName, iconSize, iconColor, titleColor } = this.props;
81+
if (logoName) {
82+
const logo = await getImageSource(
83+
logoName,
84+
iconSize,
85+
iconColor || titleColor
6686
);
87+
this.setState({ logo });
88+
// eslint-disable-next-line react/destructuring-assignment
89+
} else if (this.state.logo) {
90+
this.setState({ logo: undefined });
6791
}
68-
if (props.navIconName) {
69-
getImageSource(props.navIconName, size, color).then(navIcon =>
70-
this.setState({ navIcon })
92+
}
93+
94+
async updateNavIconSource() {
95+
const { navIconName, iconSize, iconColor, titleColor } = this.props;
96+
if (navIconName) {
97+
const navIcon = await getImageSource(
98+
navIconName,
99+
iconSize,
100+
iconColor || titleColor
71101
);
102+
console.log({ navIcon });
103+
this.setState({ navIcon });
104+
// eslint-disable-next-line react/destructuring-assignment
105+
} else if (this.state.navIcon) {
106+
this.setState({ navIcon: undefined });
72107
}
73-
if (props.overflowIconName) {
74-
getImageSource(props.overflowIconName, size, color).then(overflowIcon =>
75-
this.setState({ overflowIcon })
108+
}
109+
110+
async updateOverflowIconSource() {
111+
const { overflowIconName, iconSize, iconColor, titleColor } = this.props;
112+
if (overflowIconName) {
113+
const overflowIcon = await getImageSource(
114+
overflowIconName,
115+
iconSize,
116+
iconColor || titleColor
76117
);
118+
this.setState({ overflowIcon });
119+
// eslint-disable-next-line react/destructuring-assignment
120+
} else if (this.state.overflowIcon) {
121+
this.setState({ overflowIcon: undefined });
77122
}
123+
}
78124

79-
Promise.all(
80-
(props.actions || []).map(action => {
125+
async updateActionIconSources() {
126+
const { actions, iconSize, iconColor, titleColor } = this.props;
127+
const updatedActions = await Promise.all(
128+
(actions || []).map(action => {
81129
if (action.iconName) {
82130
return getImageSource(
83131
action.iconName,
84-
action.iconSize || size,
85-
action.iconColor || color
132+
action.iconSize || iconSize,
133+
action.iconColor || iconColor || titleColor
86134
).then(icon => ({ ...action, icon }));
87135
}
88136
return Promise.resolve(action);
89137
})
90-
).then(actions => this.setState({ actions }));
138+
);
139+
this.setState({ actions: updatedActions });
91140
}
92141

93142
render() {

0 commit comments

Comments
 (0)