My page has only a single TextInput, and I have passed in the autoFocus prop: autoFocus: true.
<TextInput
   style={styles.textInput}
   placeholder="Quiz Deck Title"
   autoFocus={true}
   value={this.state.title}
   onChangeText={(title) => this.controlledTextInput(title)}
/>
What I am trying to avoid is requiring the user to "click" in the TextInput box before the keyboard pops up.  
But I would also like to have the soft keyboard also open automatically (if the device does not have a hardware keyboard).
Is there way to make this happen in react native? I am developing for both ios and android.
If it matters, my page is navigated to via TabNavigator.
I mention this because a comment to another similar SO question (see below) suggests they had a similar issue when they arrived at their page using StackNavigator.
Note on Similar SO questions:
How to open keyboard automatically in React Native?
:  does not provide a solution, and comments by others suggest the same results as myself: input is focused, but keyboard does not automatically open.
Close/hide the Android Soft Keyboard
 and Android: show soft keyboard automatically when focus is on an EditText
: are using native android code (java), not react native code (javascript).
Note: I am developing using the android emulator Nexus 6P with android 23 (as recommended), and ios simulator with iPhone 6s, as I do not have physical devices.
Edit: Adding Requested Code
NewDeck.js (the view I want the keyboard to auto pop up on):
import React from 'react';
import { connect } from 'react-redux';
import { View, Text, TouchableOpacity,
         TextInput, KeyboardAvoidingView,
         StyleSheet, Platform,
       } from 'react-native';
import StyledButton from '../components/StyledButton';
import { saveDeck }      from '../store/decks/actionCreators';
import { getDeckList }   from '../store/decks/selectors';
import { fetchDecks }    from '../utils/api';
import { saveDeckTitle } from '../utils/api';
       } from '../utils/colors';
import { titleCase, stripInvalidChars, makeStringUnique }
  from '../utils/helpers';
import { white, gray, primaryColor, primaryColorDark, primaryColorLight,
class NewDeck extends React.Component {    
  state = {
    title: '',
    canSubmit: false,
  }    
  componentDidMount () {
    this.textInputRef.focus()
  }
  controlledTextInput(title){
    title = titleCase(stripInvalidChars(title));
    const canSubmit = this.isValidInput(title);
    this.setState({ title, canSubmit });
  }    
  isValidInput(text){
    return text.trim() !== '';
  }
  onBlur(){
    title = this.state.title.trim();
    const unique = makeStringUnique(title, this.props.existingTitles);
    this.setState({ title: unique });
  }    
  onSubmit(){
    let title = this.state.title.trim();    
    title = makeStringUnique(title, this.props.existingTitles)
    saveDeckTitle(title)    
    this.props.navigation.navigate('Home');
  }    
  render() {
      return (
          <View style={styles.container}>
            <View style={[styles.cardContainer, {flex: 1}]}>
              <Text  style={styles.instructionsText}
                >
                Title for your New Quiz Deck
              </Text>
              <KeyboardAvoidingView {...keyboardAvoidingViewProps}>
                <TextInput
                  style={styles.textInput}
                  placeholder="Quiz Deck Title"
                  value={this.state.title}
                  onChangeText={(title) => this.controlledTextInput(title)}
                  /* autoFocus={true} */
                  ref={ref => this.textInputRef = ref}
                  />
              </KeyboardAvoidingView>
            </View>
            <KeyboardAvoidingView
              {...keyboardAvoidingViewProps}
              style={[styles.buttonsContainer, styles.buttonContainer]}
              >
              <StyledButton
                style={[styles.item, style={flex: 2}]}
                onPress={() => this.onSubmit()}
                disabled={!this.state.canSubmit}
                >
                <Text>
                  Submit
                </Text>
              </StyledButton>
            </KeyboardAvoidingView>
          </View>
      );
  }
}
const keyboardAvoidingViewProps = {
  behavior: 'padding',
};
// ...styles definition here, - I posted it in a later code block, to minimize 
// clutter, in the event that it is irrelevant to this issue
function mapStoreToProps(store){
  const decks  = getDeckList(store) || null;
  // ensure titles are unique (better UX than if just make id unique)
  const existingTitles = decks && decks.map(deck => {
    return deck.title
  }) || [];
  return {
    existingTitles,
  }
}
export default connect(mapStoreToProps)(NewDeck);
TabNavigator and StackNavigator code (in App.js):
// ... the TabNavigator I'm using:
import { TabNavigator, StackNavigator } from 'react-navigation';
//... the class's render method, uses StackNavigator (as MainNavigation)
render(){
    return (
      <Provider store={createStore(rootReducer)}>
        <View style={{flex:1}}>
          <AppStatusBar
            backgroundColor={primaryColor}
            barStyle="light-content"
            />
          <MainNavigation />
        </View>
      </Provider>
    );
  }
}
// ... 
const Tabs = TabNavigator(
  {
    DeckList: {
      screen: DeckList,
      navigationOptions: {
        tabBarLabel: 'Quiz Decks',
        tabBarIcon: ({ tintColor }) =>  // icons only show in ios
          <Ionicons name='ios-bookmarks' size={30} color={tintColor} />
      },
    },
    NewDeck: {
      screen: NewDeck,
      navigationOptions: {
        tabBarLabel: 'Create New Deck',
        tabBarIcon: ({ tintColor }) => // icons only show in ios
          <FontAwesome name='plus-square' size={30} color={tintColor} />
      },
    },
  },
  {
    navigationOptions: {
      // do-not-display page headers for Tab Navigation
      header: null
    },    
    tabBarOptions: {
      // ios icon and text color; android text color
      activeTintColor:   Platform.OS === 'ios' ? primaryColor : white,    
      pressColor: white,    
      indicatorStyle: {
        backgroundColor: primaryColorDark,
        height: 3,
      },    
      style: {
        height: 56,
        backgroundColor: Platform.OS === 'ios' ? white  : primaryColor,    
        shadowColor: 'rgba(0, 0, 0, 0.24)',
        shadowOffset: {
          width: 0,
          height: 3
        },
        shadowRadius: 6,
        shadowOpacity: 1
      }
    }
  }
);
//... StackNavigator uses TabNavigator (as Tabs)
const stackScreenNavigationOptions = {
  headerTintColor:   white,
  headerStyle: {
    backgroundColor: primaryColor,
  }
};
const MainNavigation = StackNavigator(
  //  RouteConfigs: This is analogous to defining Routes in a web app
  {
    Home: {
      screen: Tabs,  // Which also loads the first Tab (DeckList)
    },
    Deck: {
      screen: Deck,
      navigationOptions: stackScreenNavigationOptions,
    },
    Quiz: {
      screen: Quiz,
      navigationOptions: stackScreenNavigationOptions,
    },
    NewDeck: {
      screen: NewDeck,
      navigationOptions: stackScreenNavigationOptions,
    },
    NewCard: {
      screen: NewCard,
      navigationOptions: stackScreenNavigationOptions,
    },
  },
);
This is the styles definition for NewDeck.js
const styles = StyleSheet.create({
  // CONTAINER styles
  wrapper: {
    // this was the previous container style
      flex: 1,
      backgroundColor: white,
      alignItems: 'center',
      justifyContent: 'center',
    },
  container: {
    flex: 1,
    backgroundColor: white,
    alignItems: 'center',
    justifyContent: 'space-between',
    padding: 10,
    paddingTop: 30,
    paddingBottom: 5,
  },
  cardContainer: {
    flex: 1,
    justifyContent: 'flex-start',
    alignSelf: 'stretch',
    backgroundColor: '#fefefe',
    padding:     20,
    marginLeft:  30,
    marginRight: 30,
    marginTop:   10,
    borderRadius: Platform.OS === 'ios' ? 20 : 10,
    shadowRadius: 3,
    shadowOpacity: 0.8,
    shadowColor: 'rgba(0, 0, 0, 0.24)',
    shadowOffset: {
      width: 0,
      height: 3,
    },
    marginBottom:20,
  },
  buttonsContainer: {
    flex: 3,
    alignSelf: 'stretch',
    justifyContent: 'flex-start',
  },
  buttonContainer: {
    justifyContent: 'center',
    margin: 10,
  },
  // TEXT Styles
  instructionsText: {
    flex: 1,
    fontSize: 20,
    color: gray,
    alignSelf: 'center',
    textAlign: 'center',
  },
  // INPUTTEXT styles
  textInput: {
    fontSize: 27,
    color: primaryColor,
    alignSelf: 'stretch',
    flexWrap:  'wrap',
    textAlign: 'center',
    marginTop: 10,
  },
});
StyledButton.js (Basically, TouchableOpacity with platform-specific styling, for universal use across the app):  
import React from 'react';
import { Text, TouchableOpacity, StyleSheet, Platform } from 'react-native';
import { white, gray, primaryColor, primaryColorLight, primaryColorDark} from '../utils/colors';
export default function TextButton({ children, onPress, customColor, disabled=false }) {
  const disabledColor = disabled ? gray : null;
  const backgroundColor = Platform.OS==='ios' ? white : disabledColor || customColor || primaryColorLight;
  const borderColor     = Platform.OS==='ios' ? disabledColor || customColor || primaryColorDark
  const textColor       = Platform.OS==='ios' ? disabledColor || customColor || primaryColor  : white;
  const btnStyle = Platform.OS==='ios' ? styles.iosBtn : styles.androidBtn;
  const txtStyle = styles.txtDefault;
  const btnColor = { backgroundColor, borderColor };
  const txtColor = { color: textColor };
  return (
      <TouchableOpacity
        onPress={onPress}
        disabled={disabled}
        style={[btnStyle, btnColor]}
        >
        <Text
          style={[styles.txtDefault, txtColor]}
          >
          {children}
        </Text>
      </TouchableOpacity>
  );
}
const styles = StyleSheet.create({
  txtDefault: {
    textAlign: 'center',
    // because of bleeding of white text to colored background on android,
    // enlarge text (or increase fontWeight) for better readability
    fontSize: Platform.OS==='ios' ? 15 : 18,
    padding: 10,
  },
  iosBtn: {
    height: 45,
    borderRadius: 7,
    alignSelf:      'center',
    justifyContent: 'center',
    alignItems:     'center',
    // ios only settings
    borderColor:   primaryColorDark,
    borderWidth:   1,
    borderRadius:  3,
    paddingLeft:  25,
    paddingRight: 25,
  },
  androidBtn: {
    height: 45,
    borderRadius: 5,
    alignSelf:      'center',
    justifyContent: 'center',
    alignItems:     'center',
    // android- only settings
    // (padding accepts clicks, vs. margin === no-click zone)
    padding: 20,
    paddingLeft:  15,
    paddingRight: 15,
  },
});
// ios has white buttons with colored outlines and colored text
// android has colored buttons with white text
// Pass in a button color, or it defaults to the App's primary colors
 
     
     
     
     
    