React-native, react-native-router-flux && Custom Icon on Drawer NOT working

1.7k views Asked by At

Until now it renders but doesn't open the drawer.

I believe is something associated to the references but I'm not sure.

if someone could help me it will be awesome.

router.js

import React, { Component } from 'react';
import { Actions, Router, Scene } from 'react-native-router-flux';

import Dashboard from './components/dashboard';
import Home from './components/home';
import ViewCamera from './components/view-camera';
import Register from './components/register';
import SideDrawer from './components/sideDrawer';
import TabIcon from './components/tabIcon';

function openDrawer() {
  return (<TabIcon
    press={() => {
      Actions.refresh({ key: 'drawer', open: true })
    }}
  />);
}

class RouterComponent extends Component {
  render() {
    return (
      <Router>
        <Scene key="root">
          <Scene
            panHandlers={null}
            key="home"
            hideNavBar component={Home} title="Login" initial
          />
          <Scene
            panHandlers={null}
            key="viewCamera"
            hideNavBar component={ViewCamera} title="Captura del Documento"
          />
          <Scene
            panHandlers={null}
            key="register"
            hideNavBar component={Register} title="Registro"
          />
        </Scene>
        <Scene
          key="drawer" component={SideDrawer}
        >
          <Scene
            key="tabs"
            tabs
          >
            <Scene
              initial
              panHandlers={null}
              component={Dashboard}
              hideTabBar
              key="dashboard"
              title="Propuestas"
              renderLeftButton={openDrawer}
            />
            {/*<Scene panHandlers={null} key="pollCreation" component={Poll} />*/}
          </Scene>
        </Scene>
      </Router>
    );
  }
}
export default RouterComponent;

components/tabIcon.js

import React, {
  Component,
  PropTypes,
  StyleSheet
} from 'react';

import {
  Text,
} from 'react-native';

import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
import { Button } from 'native-base';
import { Actions } from 'react-native-router-flux';

const propTypes = {
  selected: PropTypes.bool,
  title: PropTypes.string,
};

class TabIcon extends Component {
  render() {
    return (
      <Button
        transparent
        onPress={this.openDrawer.bind(this)} style={styles.navButton}
        style={{ backgroundColor: 'rgba(0,0,0,0)' }}
      >
        <Text>
          <MaterialIcons name="menu" size={30} />
        </Text>
      </Button>
    );
  }
  openDrawer = () => {
    Actions.get('drawer').ref.toggle();
  };
}
TabIcon.propTypes = propTypes;

const styles = {
  navButton: {
    alignItems: 'flex-end',
    flex: 1,
  }
};

export default TabIcon;

sideDrawer.js

import React, { Component, PropTypes } from 'react';

import {
  BackAndroid,
  StyleSheet,
  Text,
  View,
} from 'react-native';
import { Drawer } from 'native-base';

import { DefaultRenderer, Actions } from 'react-native-router-flux';
import SideBar from './sidebar';

const propTypes = {
  navigationState: PropTypes.object,
};

class SideDrawer extends Component {
  static propTypes = {
    closeDrawer: React.PropTypes.func,
    drawerState: React.PropTypes.string,
  }

  constructor(props) {
    super(props);
    this.state = {
      animatingLoadingSpinner: false,
      url: 'polls',
    };
  }

  componentDidMount() {
    BackAndroid.addEventListener('hardwareBackPress', () => {
      Actions.pollCreation();
    });
    Actions.refresh({ key: 'drawer', ref: this.refs.navigation });
  }

  finishSpinnerAnimation() {
    this.setState({
      animatingLoadingSpinner: false
    });
  }

  startSpinnerAnimation() {
    this.setState({
      animatingLoadingSpinner: true
    });
  }


  noServerConnection() {
    return (
      <View style={styles.errorBody} >
        <Text > No es posible la conexión con Nuestros servidores </Text>
      </View>
    );
  }

  render() {
    const state = this.props.navigationState;
    const children = state.children;
    return (
      <View style={styles.container} >
        <Drawer
          ref='navigation'
          type="overlay"
          tweenDuration={150}
          content={
            <SideBar
              closeDrawer={() => {
                this.drawer.close();
               }}
            />
          }
          tapToClose
          acceptPan={false}
          openDrawerOffset={0.2}
          panCloseMask={0.2}
          styles={{
            drawer: {
              shadowColor: '#000000',
              shadowOpacity: 0.8,
              shadowRadius: 3,
            },
          }}
          tweenHandler={(ratio) => {  // eslint-disable-line
            return {
              drawer: { shadowRadius: ratio < 0.2 ? ratio * 5 * 5 : 5 },
              main: {
                opacity: (2 - ratio) / 2,
              },
            };
          }}
          negotiatePan
          onOpen={() => Actions.refresh({ key: state.key, open: true })}
          onClose={() => Actions.refresh({ key: state.key, open: false })}
        >

          {/*<View style={{ marginTop: 45 }} />*/}
          <DefaultRenderer navigationState={children[0]} onNavigate={this.props.onNavigate} />
        </Drawer>
      </View>
    );
  }

}

let WEBVIEW_REF = 'webview';
const BGWASH = '#F6F6F6';

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: BGWASH,
  },
  addressBarRow: {
    flexDirection: 'row',
    height: 10,
  },
  errorBody: {
    alignItems: 'center',
    justifyContent: 'center',
  },
  navButton: {
    alignItems: 'flex-end',
    flex: 1,
  },
  navText: {
    fontSize: 18,
  },
  navTextContainer: {
    alignItems: 'center',
    flex: 8,
    justifyContent: 'center',
  },
});

SideDrawer.propTypes = propTypes;
export default SideDrawer;
1

There are 1 answers

0
jasmo2 On BEST ANSWER

What I did was base myself on nativebase and on its example .

  1. Add Redux

    Actions && Reducers

    drawerActions.js

    import type { Action } from './types';
    
    const OPEN_DRAWER = 'open_drawer';
    const CLOSE_DRAWER = 'close_drawer';
    
    export function openDrawer():Action {
      return {
        type: OPEN_DRAWER,
      };
    }
    
    export function closeDrawer():Action {
      return {
        type: CLOSE_DRAWER,
      };
    }
    

drawerReducer.js

import type { Action } from '../actions/types';

export const OPEN_DRAWER = 'open_drawer';
export const CLOSE_DRAWER = 'close_drawer';

export type State = {
    drawerState: string,
    drawerDisabled: boolean
}

const initialState = {
  drawerState: 'closed',
  drawerDisabled: true,
};

export default function (state:State = initialState, action:Action): State {
  if (action.type === OPEN_DRAWER) {
    return {
      ...state,
      drawerState: 'opened',
    };
  }

  if (action.type === CLOSE_DRAWER) {
    return {
      ...state,
      drawerState: 'closed',
    };
  }

  return state;
}
  1. Using react-redux I connected the sideDrawer.js component import React, { Component, PropTypes } from 'react'; import { connect } from 'react-redux';

    import {
      BackAndroid,
      StyleSheet,
      Text,
      View,
    } from 'react-native';
    import { Drawer } from 'native-base';
    
    import { DefaultRenderer, Actions } from 'react-native-router-flux';
    import SideBar from './sidebar';
    import { closeDrawer } from '../actions';
    
    const propTypes = {
      navigationState: PropTypes.object,
    };
    
    class SideDrawer extends Component {
      static propTypes = {
        closeDrawer: React.PropTypes.func,
        drawerState: React.PropTypes.string,
      }
    
      constructor(props) {
        super(props);
        this.state = {
          animatingLoadingSpinner: false,
          url: 'polls',
        };
      }
    
      componentDidMount() {
        BackAndroid.addEventListener('hardwareBackPress', () => {
          Actions.pollCreation();
        });
        Actions.refresh({ key: 'drawer', ref: this.refs.navigation });
      }
    
      componentDidUpdate() {
        if (this.props.drawerState === 'opened') {
          this.openDrawer();
        }
    
        if (this.props.drawerState === 'closed') {
          this.refs.navigation.close();
        }
      }
    
      openDrawer() {
        this.refs.navigation.open();
      }
    
      closeDrawer() {
        console.log(`onClose: ${this.props.drawerState}`);
    
        if (this.props.drawerState === 'opened') {
          this.props.closeDrawer();
        }
      }
    
      finishSpinnerAnimation() {
        this.setState({
          animatingLoadingSpinner: false
        });
      }
    
      startSpinnerAnimation() {
        this.setState({
          animatingLoadingSpinner: true
        });
      }
    
    
      noServerConnection() {
        return (
          <View style={styles.errorBody} >
            <Text > No es posible la conexión con Nuestros servidores </Text>
          </View>
        );
      }
    
      render() {
        const state = this.props.navigationState;
        const children = state.children;
        return (
          <View style={styles.container} >
            <Drawer
              ref='navigation'
              type="overlay"
              tweenDuration={150}
              content={
                <SideBar
                  closeDrawer={() => this.closeDrawer()}
                />
              }
              tapToClose
              acceptPan={false}
              openDrawerOffset={0.2}
              panCloseMask={0.2}
              styles={{
                drawer: {
                  shadowColor: '#000000',
                  shadowOpacity: 0.8,
                  shadowRadius: 3,
                },
              }}
              tweenHandler={(ratio) => {  // eslint-disable-line
                return {
                  drawer: { shadowRadius: ratio < 0.2 ? ratio * 5 * 5 : 5 },
                  main: {
                    opacity: (2 - ratio) / 2,
                  },
                };
              }}
              negotiatePan
              onCloseStart={this.closeDrawer.bind(this)}
            >
              <DefaultRenderer navigationState={children[0]} onNavigate={this.props.onNavigate} />
            </Drawer>
          </View>
        );
      }
    
    }
    
    const BGWASH = '#F6F6F6';
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        backgroundColor: BGWASH,
      },
      addressBarRow: {
        flexDirection: 'row',
        height: 10,
      },
      errorBody: {
        alignItems: 'center',
        justifyContent: 'center',
      },
      navButton: {
        alignItems: 'flex-end',
        flex: 1,
      },
      navText: {
        fontSize: 18,
      },
      navTextContainer: {
        alignItems: 'center',
        flex: 8,
        justifyContent: 'center',
      },
    });
    
    SideDrawer.propTypes = propTypes;
    const mapStateToProps = (state) => {
      const { url } = state.polls;
      const drawerState = state.drawer.drawerState;
      return { drawerState, url };
    };
    const mapDispatchToProps = dispatch => ({
      closeDrawer: () => dispatch(closeDrawer()),
    });
    
    export default connect(mapStateToProps, mapDispatchToProps)(SideDrawer);
    
  2. Connect the tabIcon.js also, it will be in charge to open the drawer when tap.

    import React, {
      Component,
      PropTypes,
      StyleSheet
    } from 'react';
    
    import {
      Text,
    } from 'react-native';
    
    import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
    import { Button } from 'native-base';
    import { Actions } from 'react-native-router-flux';
    import { connect } from 'react-redux';
    import { openDrawer } from '../actions';
    
    const propTypes = {
      selected: PropTypes.bool,
      title: PropTypes.string,
    };
    
    class TabIcon extends Component {
      openDrawer = () => {
        this.props.openDrawer();
        // Actions.refresh({ key: 'drawer', open: value => !value });
      };
      render() {
        return (
          <Button
            transparent
            onPress={this.openDrawer.bind(this)} style={styles.navButton}
            style={{ backgroundColor: 'rgba(0,0,0,0)' }}
          >
            <Text>
              <MaterialIcons name="menu" size={30} />
            </Text>
          </Button>
        );
      }
    }
    TabIcon.propTypes = propTypes;
    
    const styles = {
      navButton: {
        alignItems: 'flex-end',
        flex: 1,
      }
    };
    
    export default connect(null, { openDrawer })(TabIcon);