0

I'm working in an older codebase using React-Native 0.63 and I'm trying to add RNPickerSelect to the login page of an app. The app uses Redux for State management, I've created Types, Reducers, Selectors, Actions, and an Initial State for the Redux. After Importing the RNPickerSelect and the Picker appears on the screen, and allows interaction but whenever a value is selected the app crashes and gives no error.
Here's the LoginScreen.js Page

import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { Text, StatusBar, View, ScrollView, Platform, Image } from 'react-native'
import Config from 'react-native-config'
import { connect } from 'react-redux'
import { compose } from 'redux'
import { Colors } from '../Themes/'
import LoginActions, { LoginSelectors } from '../Redux/LoginRedux'
import RNPickerSelect  from 'react-native-picker-select'

// Styles
import styles from './Styles/LoginScreenStyle'
import Logo from '../Components/Logo'
import LoginForm from '../Components/LoginForm'
import { withNavigation } from 'react-navigation'

import I18n from '../I18n/'

class LoginScreen extends Component {
  static propTypes = {
    userName: PropTypes.string,
    password: PropTypes.string,
    pickerValue: PropTypes.string,
    updateUserName: PropTypes.func,
    updatePassword: PropTypes.func,
    updatePickerValue: PropTypes.func,
    navigation: PropTypes.object,
    doLogin: PropTypes.func,
    siteUrl: PropTypes.string,
    updateSiteUrl: PropTypes.func,
    isLoggingIn: PropTypes.bool,
    initialize: PropTypes.func
  }

  componentDidMount () {
    const { userName, password, siteUrl, initialize } = this.props
    if (!userName && !password && !siteUrl) {
      initialize(Config.USER_NAME, Config.PASSWORD, Config.SITE_URL)
    }
  }

  handlePressLogin = () => {
    const { userName, password, siteUrl } = this.props
    this.props.doLogin(userName, password, siteUrl)
  }

  render () {
    const { userName, password, siteUrl, updateUserName, updatePassword, updateSiteUrl, isLoggingIn, updatePickerValue, pickerValue } = this.props
    
    return (
      <ScrollView contentContainerStyle={styles.mainScrollViewContainer}>
        <View style={styles.contentArea}>
          <View style={{backgroundColor: 'red'}}>
            <StatusBar
              barStyle={Platform.OS == 'ios' ? 'dark-content' : 'light-content'}
              backgroundColor={Colors.primaryColor}
            />
          </View>
          <View style={styles.formViewContainer}>
            <Logo size='small' />
            <View style={styles.welcomeTextContainer}>
              <Text style={styles.LogoText}>{I18n.t('loginPageWelcomeText')}</Text>
            </View>
            <RNPickerSelect
              onValueChange={updatePickerValue}
              items={[    
                { label: 'Option 1', value: 'option1' },    
                { label: 'Option 2', value: 'option2' },    
                { label: 'Option 3', value: 'option3' },  
              ]}
              value={pickerValue}
            />
            <LoginForm
              userName={userName}
              onUserNameChange={updateUserName}
              password={password}
              onPasswordChange={updatePassword}
              siteUrl={siteUrl}
              onSiteUrlChange={updateSiteUrl}
              handlePressLogin={this.handlePressLogin}
              isLogginIn={isLoggingIn}
            />
          </View>
        </View>
        <View style={{marginBottom: 20}}><Image resizeMode='contain' style={{width: '100%'}} source={require('../Images/footer.jpeg')} /></View>
      </ScrollView>
    )
  }
}

const mapStateToProps = (state) => {
  return {
    userName: LoginSelectors.getUserName(state),
    password: LoginSelectors.getPassword(state),
    pickerValue: LoginSelectors.getPickerValue(state),
    siteUrl: LoginSelectors.getSiteUrl(state),
    isLoggingIn: LoginSelectors.isLoggingIn(state),
  }
}

const mapDispatchToProps = {
  updateUserName: LoginActions.updateUserName,
  updatePassword: LoginActions.updatePassword,
  updateSiteUrl: LoginActions.updateSiteUrl,
  updatePickerValue: LoginActions.updatePickerValue,
  doLogin: LoginActions.loginRequest,
  initialize: LoginActions.initialize
}

export default compose(
  connect(mapStateToProps, mapDispatchToProps),
  withNavigation
)(LoginScreen)

And here's my redux js

import { createReducer, createActions } from 'reduxsauce'
import { StartupTypes } from './StartupRedux'
import Immutable from 'seamless-immutable'

/* ------------- Types and Action Creators ------------- */

const { Types, Creators } = createActions({
  initialize: ['userName', 'password', 'siteUrl'],
  updateSiteUrl: ['siteUrl'],
  updateUserName: ['userName'],
  updatePassword: ['password'],
  updatePickerValue: ['pickerValue'],
  loginRequest: ['userName', 'password', 'siteUrl'],
  loginSuccess: ['data'],
  loginFailure: null,
  logout: null
})

export const LoginTypes = Types
export default Creators

/* ------------- Initial State ------------- */

export const INITIAL_STATE = Immutable({
  userName: '',
  password: '',
  siteUrl: '',
  pickerValue: '',
  accessToken: null,
  displayName: '',
  vendorId: null,
  fetching: null,
  payload: null,
  error: null,
})

/* ------------- Selectors ------------- */

export const LoginSelectors = {
  getData: state => state.data,
  getSiteUrl: state => state.login.siteUrl,
  getUserName: state => state.login.userName,
  getPassword: state => state.login.password,
  getPickerValue: state => state.login.pickerValue,
  isLoggingIn: state => state.login.fetching,
  getAccessToken: state => state.login.accessToken,
  getDisplayName: state => state.login.displayName,
  getVendorId: state => state.login.vendorId,
}

/* ------------- Reducers ------------- */

export const initialize = (state, { userName, password, siteUrl }) =>
  state.merge({ userName, password, siteUrl })

export const request = (state, { data }) =>
  state.merge({ fetching: true, data, payload: null })

export const success = (state, action) => {
  const { data: { token: accessToken, store_name: displayName, store_id: vendorId } } = action
  //console.log(vendorId)
  return state.merge({ fetching: false, error: null, password: '', accessToken, displayName, vendorId })
}

export const updateUserName = (state, action) => {
  const { userName } = action
  return state.merge({ userName })
}

export const updatePassword = (state, action) => {
  const { password } = action
  return state.merge({ password })
}

export const updatePickerValue = (state, action) => {
  const { pickerValue } = action
  return state.merge({ pickerValue })
}

export const updateSiteUrl = (state, action) => {
  const { siteUrl } = action
  return state.merge({ siteUrl })
}


// Something went wrong somewhere.
export const failure = state =>
  state.merge({ fetching: false, error: true, payload: null })

export const logout = state =>
  INITIAL_STATE

export const onStartup = state =>
  state.merge({ fetching: false })

/* ------------- Hookup Reducers To Types ------------- */

export const reducer = createReducer(INITIAL_STATE, {
  [Types.LOGIN_REQUEST]: request,
  [Types.LOGIN_SUCCESS]: success,
  [Types.LOGIN_FAILURE]: failure,
  [Types.UPDATE_USER_NAME]: updateUserName,
  [Types.UPDATE_PASSWORD]: updatePassword,
  [Types.UPDATE_SITE_URL]: updateSiteUrl,
  [Types.UPDATE_PICKER_VALUE]: updatePickerValue,
  [Types.LOGOUT]: logout,
  [Types.INITIALIZE]: initialize,
  [StartupTypes.STARTUP]: onStartup,
})

I've tried different pickers but RNPickerSelect seems to be the only one that even starts to display when I use it.
I've also tried putting it a level lower in the <LoginForm> component but for the sake of trying to make it easier on myself I've moved it up into LoginScreen instead.

I'm very new to React/React Native as well as Redux so I apologize if this is a bit of a noob question. Any help is greatly appreciated!

0 Answers0