I'm learning the ropes with React Native and React Navigator at the moment and I've come across something in development where I feel like I want to implement the DRY (don't repeat yourself) technique.
Here's my component code:
export default class App extends React.Component {
render() {
const MainNavigator = TabNavigator({
welcome: { screen: WelcomeScreen },
auth: { screen: AuthScreen },
main: {
screen: TabNavigator({
map: { screen: MapScreen },
deck: { screen: DeckScreen },
review: {
screen: StackNavigator({
review: { screen: ReviewScreen },
settings: { screen: SettingsScreen }
})
}
}, {
tabBarPosition: 'bottom',
lazyLoad: true,
animationEnabled: false,
swipeEnabled: false
})
}
}, {
tabBarPosition: 'bottom',
lazyLoad: true,
animationEnabled: false,
swipeEnabled: false
});
return <MainNavigator />;
}
}
As you can see, I have the following chunk of repeatable code:
tabBarPosition: 'bottom',
lazyLoad: true,
animationEnabled: false,
swipeEnabled: false
I tried to refactor the same way that you would do styles in React components like this:
export default class App extends React.Component {
render() {
const MainNavigator = TabNavigator({
welcome: { screen: WelcomeScreen },
auth: { screen: AuthScreen },
main: {
screen: TabNavigator({
map: { screen: MapScreen },
deck: { screen: DeckScreen },
review: {
screen: StackNavigator({
review: { screen: ReviewScreen },
settings: { screen: SettingsScreen }
})
}
}, { defaultTabStyles })
}
}, { defaultTabStyles });
return <MainNavigator />;
}
}
const defaultTabStyles = {
tabBarPosition: 'bottom',
lazyLoad: true,
animationEnabled: false,
swipeEnabled: false
};
As you can see, this is a much cleaner way of doing things if it would work. But it doesn't work, so is there a way of refactoring this correctly or do I need to stick with my original implementation?
It looks like you are wrapping your defaultTabStyles
object in curly braces, which thanks to the ES6 object property shorthand creates the following object:
{
defaultTabStyles:
{
animationEnabled: false,
lazeLoad: true,
swipeEnabled: false,
tabBarPosition: 'bottom',
},
}
Which contains none of the keys the navigator is looking for. Try removing the curly braces:
export default class App extends React.Component {
render() {
const MainNavigator = TabNavigator({
welcome: { screen: WelcomeScreen },
auth: { screen: AuthScreen },
main: {
screen: TabNavigator({
map: { screen: MapScreen },
deck: { screen: DeckScreen },
review: {
screen: StackNavigator({
review: { screen: ReviewScreen },
settings: { screen: SettingsScreen }
})
}
}, defaultTabStyles) // instead of { defaultTabStyles }
}
}, defaultTabStyles); // instead of { defaultTabStyles }
return <MainNavigator />;
}
}
const defaultTabStyles = {
tabBarPosition: 'bottom',
lazyLoad: true,
animationEnabled: false,
swipeEnabled: false
};
Furthermore, to keep it DRY further down the road, you can override default options for specific navigators using spread syntax:
const mainScreenTabStyles = {
...defaultTabStyles,
tabBarPosition: 'top',
}