I've created a React Native app with navigation provided by react-navigation, also integrating redux with react-navigation-redux-helpers, and I'm trying to figure out a good way of implementing a globally-available 'SignOutHeaderButton' component that, when pressed, will dispatch a redux action and perform a navigation operation.
At the moment, I'm having to pass a function via screenProps from the application root component, which is the function that dispatches the redux action. This function is then passed to the UpdatesListView container component via screenProps, and is then passed into the SignOutHeaderButton common component as a prop via navigationOptions.
Is there a better way in which I can implement this so that I don't have to pass any props into the SignOutHeaderButton component and without having to instantiate a signOut() function within each container component in the application from which there will be a 'Sign Out' button?
App.js:
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { reduxifyNavigator } from 'react-navigation-redux-helpers';
import { PersistGate } from 'redux-persist/integration/react';
import { Provider, connect } from 'react-redux';
import { appContainer } from './src/navigators';
import { store, persistor } from './src/store/configureStore';
import { signOut } from './src/actions/auth';
const app = reduxifyNavigator(appContainer, 'root');
const mapStateToProps = state => {
return {
state: state.navReducer
}
}
const AppWithNavigationState = connect(mapStateToProps)(app);
export default class App extends React.Component {
signOut() {
store.dispatch(signOut());
}
render() {
return (
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<AppWithNavigationState
screenProps={{
signOut: this.signOut
}} />
</PersistGate>
</Provider>
)
}
}
UpdatesListView.js:
import React from 'react';
import { View, Container, Content, Text, Button } from 'native-base';
import { connect } from 'react-redux';
import SignOutHeaderButton from '../components/common/SignOutHeaderButton';
class UpdatesListView extends React.Component {
constructor(props) {
super(props);
}
static navigationOptions = ({ navigation }) => {
return {
headerTitle: 'Updates',
headerRight: <SignOutHeaderButton signOut={navigation.getParam('signOut')} />
}
}
componentDidMount() {
this.props.navigation.setParams({
signOut: this.props.screenProps.signOut
})
}
render() {
return (
<Container>
<Text>UpdatesListView</Text>
</Container>
)
}
}
const mapStatetoProps = state => {
return {
updates: state.updatesReducer,
tags: state.tagsReducer
}
}
export default connect(mapStateToProps)(UpdatesListView);
SignOutHeaderButton.js:
import React from 'react';
import { Button } from 'react-native';
import { withNavigation } from 'react-navigation';
class SignOutHeaderButton extends React.Component {
constructor(props) {
super(props);
}
signOut() {
this.props.signOut();
this.props.navigation.navigate('AuthStack');
}
render() {
return (
<Button
title="Sign Out"
onPress={this.signOut} />
)
}
}
export default withNavigation(SignOutHeaderButton);
