11

we are currently running React-Native 0.33

We are trying to use the refs to go from 1 text input to another when they hit the next button. Classic username to password.

Anyone have any idea? Below is the code we are using. From other posts I've found on stack this is what they've done; however, it's telling us that this.refs is undefined.

UPDATE So I've narrowed the problem down to

 render() {
    return (
      <Navigator
          renderScene={this.renderScene.bind(this)}
          navigator={this.props.navigator}

          navigationBar={
            <Navigator.NavigationBar style={{backgroundColor: 'transparent'}}
                routeMapper={NavigationBarRouteMapper} />
          } />
    );
  }

If I just render the code below in the renderScene function inside of the original render it works, however with the navigator it won't work. Does anyone know why? Or how to have the navigator show as well as render the code in renderScene to appear in the original render?

   class LoginIOS extends Component{

  constructor(props) {
    super(props);
    this.state={
      username: '',
      password: '',
      myKey: '',
    };
  }

  render() {
    return (
      <Navigator
          renderScene={this.renderScene.bind(this)}
          navigator={this.props.navigator}

          navigationBar={
            <Navigator.NavigationBar style={{backgroundColor: 'transparent'}}
                routeMapper={NavigationBarRouteMapper} />
          } />
    );
  }

  renderScene() {
    return (
      <View style={styles.credentialContainer}>
                <View style={styles.inputContainer}>
                  <Icon style={styles.inputPassword} name="person" size={28} color="#FFCD00" />
                      <View style={{flexDirection: 'row', flex: 1, marginLeft: 2, marginRight: 2, borderBottomColor: '#e0e0e0', borderBottomWidth: 2}}>
                        <TextInput 
                            ref = "FirstInput"
                            style={styles.input}
                            placeholder="Username"
                            autoCorrect={false}
                            autoCapitalize="none"
                            returnKeyType="next"
                            placeholderTextColor="#e0e0e0"
                            onChangeText={(text) => this.setState({username: text})}
                            value={this.state.username}
                            onSubmitEditing={(event) => {
                              this.refs.SecondInput.focus();
                            }}
                            >

                        </TextInput>
                      </View>
                </View>

                <View style={styles.inputContainer}>
                  <Icon style={styles.inputPassword} name="lock" size={28} color="#FFCD00" />
                      <View style={{flexDirection: 'row', flex: 1, marginLeft: 2, marginRight: 2, borderBottomColor: '#e0e0e0', borderBottomWidth: 2}}>
                        <TextInput
                            ref = "SecondInput"
                            style={styles.input}
                            placeholder="Password"
                            autoCorrect={false}
                            secureTextEntry={true}
                            placeholderTextColor="#e0e0e0"
                            onChangeText={(text) => this.setState({password: text})}
                            value={this.state.password}
                            returnKeyType="done"
                            onSubmitEditing={(event)=> {
                              this.login();
                            }}
                            focus={this.state.focusPassword}
                            >
                        </TextInput>
                      </View>
                </View>
      </View>
      );
  }
wdlax11
  • 822
  • 3
  • 11
  • 29
  • Just an attempt at solving the issue: try binding your render scene function in your constructor. So add the following line: this.renderScene = this.renderScene.bind(this) – Alex Harrison Nov 02 '16 at 20:06
  • no luck with that. tried it with the bind in the constructor and where it was in render renderScene={this.renderScene.bind(this)}. Then tried it just in the constructor. – wdlax11 Nov 02 '16 at 20:11
  • @AlexHarrison I've found it has to do with the renderScene. If I remove the navigation bar and just return the inputs in the original render it works; however, I need the navigation bar. Any idea? – wdlax11 Nov 03 '16 at 00:51

3 Answers3

12

Try setting the reference using a function. Like this:

<TextInput ref={(ref) => { this.FirstInput = ref; }} />

Then you can access to the reference with this.FirstInput instead of this.refs.FirstInput

  • If you have any experience with keyboard awareness could you potentially look at my other issue - http://stackoverflow.com/questions/40391717/react-native-keyboard-aware-scroll-view-not-working-properly – wdlax11 Nov 03 '16 at 17:38
6

For a functional component using the useRef hook. You can use achieve this easily, with...

import React, { useRef } from 'react';
import { TextInput, } from 'react-native';

function MyTextInput(){
  const textInputRef = useRef<TextInput>(null);;

  return (
    <TextInput ref={textInputRef}  />
  )
}
iamcastelli
  • 1,564
  • 2
  • 20
  • 30
0

Try changing the Navigator's renderScene callback to the following (based on Navigator documentation) cause you will need the navigator object later.

renderScene={(route, navigator) => this.renderScene(route, navigator)}

Then, use 'navigator' instead of 'this' to get the refs.

navigator.refs.SecondInput.focus()
max23_
  • 6,531
  • 4
  • 22
  • 36