0
votes

I'am using react navigation with redux and after redux integration, i got some errors on drawer close.

enter image description here

import React from "react";
. . .
import { NavigationActions } from "react-navigation";
import { StackNavigator, DrawerNavigator } from 'react-navigation';

import { addListener } from "./components/common/utils";
import Dashboard from './components/pages/Dashboard';
. . .
const MainNavigator = StackNavigator({
  Dashboard : {
    screen : Dashboard,
  },
  . . .
})

export const AppNavigator = DrawerNavigator(
  {
    Main: { screen: MainNavigator }
  }, {
    contentComponent: Menu,
    drawerWidth: 300,
    headerMode: 'screen',
    drawerPosition: 'left',
    drawerOpenRoute: 'DrawerOpen',
    drawerCloseRoute: 'DrawerClose',
    drawerToggleRoute: 'DrawerToggle',
  }
)

class AppWithNavigationState extends React.Component {
  constructor (props) {
    super(props)
    this.onBackPress = this.onBackPress.bind(this)
  }

  componentDidMount () {
    BackHandler.addEventListener('hardwareBackPress', this.onBackPress)
  }

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

  onBackPress () {
    ...
  }

  render() {
    const { dispatch, nav } = this.props;
    return (
      <AppNavigator
        navigation={{
          dispatch,
          state: nav,
          addListener,
        }}
      />
    );
  }
}

const mapStateToProps = state => ({
  nav: state.nav,
});

AppWithNavigationState.propTypes = {
  dispatch: PropTypes.func.isRequired,
  nav: PropTypes.object.isRequired,
};

export default connect(mapStateToProps)(AppWithNavigationState);

Here is my reducer:

import { fromJS } from 'immutable';
import { NavigationActions } from "react-navigation";
import { combineReducers } from "redux";

import { AppNavigator } from "../../App";
import {...} from './constants';
import { ToastAndroid } from 'react-native';

const mainAction = AppNavigator.router.getActionForPathAndParams('Main');
const initialNavState = AppNavigator.router.getStateForAction(mainAction);

function nav(state = initialNavState, action) {
  let nextState;
  switch (action.type) {
    case 'Reports':
      nextState = AppNavigator.router.getStateForAction(
        NavigationActions.back(),
        state
      );
      break;
    default:
      nextState = AppNavigator.router.getStateForAction(action, state);
      break;
  }
  return nextState || state;
}

const initialState = fromJS({
  isLoading: true,
  ...
});

function store(state = initialState, action) {
  switch (action.type) {
    case SET_IS_LOADING:
      return state.set('isLoading', action.value);
      ...
    default:
      return state;
  }
}

const AppReducer = combineReducers({
  nav,
  store,
});

export default AppReducer;

and file i call DraweOpen:

import React from "react";
import PropTypes from "prop-types";
import { TouchableOpacity } from "react-native";
import { createStructuredSelector } from 'reselect';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';

import Icon from "react-native-vector-icons/dist/MaterialIcons";
import { DrawerBurger } from "../common/styles";
import { navigate } from "../store/actions";

const drawerButton = (props) => (
  <DrawerBurger>
    <TouchableOpacity 
      onPress={() => props.navigate("DrawerOpen")}
    >
      <Icon name="menu" size={30} color="white" />
    </TouchableOpacity>
  </DrawerBurger>
);

drawerButton.propTypes = {
  navigate: PropTypes.func.isRequired,
};

const mapStateToProps = createStructuredSelector({});

const mapDispatchToProps = dispatch => (
  (
    bindActionCreators({
      navigate,
    }, dispatch)
  )
);

export default connect(mapStateToProps, mapDispatchToProps)(drawerButton);

and i call drawerButton component on navigation options like:

...
class Dashboard extends Component {
  static navigationOptions = () => ({
    headerTitle: <Header dashboard />,
    headerStyle: { backgroundColor: '#2c4e0f' },
    headerLeft: <DrawerButton />,
  });
...

I followed instructions on reactnavigation.org, also read some example code to build navigator.

Actually there was no error before redux integration and the navigator structure was same except BackHandling.

Here is my actions.js:

import { NavigationActions } from "react-navigation";
import {...} from './constants';

...
export const navigate = routeName => NavigationActions.navigate({ routeName });

My environment is:

  • react-navigation: 1.5.11
  • react-native: 0.53.0
  • react-navigation-redux-helpers: 1.0.5
  • react-redux: 5.0.7
  • redux: 3.7.2
  • node: 8.9.4
  • npm: 5.6.0

Thank for your help.

1
Can I see your reducers initialization file, and also where you're calling drawerOpen - Pritish Vaidya
Error seems to be in your DrawerView.js so would be great to see it - Théo dvn
@PritishVaidya i added related files to question. Thank you. - t13n
Can you also share your actions file? - Pritish Vaidya
@PritishVaidya added related action to question. - t13n

1 Answers

1
votes

According to the redux integration docs, it seems you've missed one step.

You need to add addNavigationHelpers from React Navigation

Usage

import {addNavigationHelpers} from 'react-navigation';

 <AppNavigator navigation={addNavigationHelpers({
        dispatch,
        state: nav,
        addListener,
      })} />