Unfocus a TextInput in React Native

2020-06-06 20:07发布

I'm building an Android app with React Native.

How can you force a TextInput to "unFocus", meaning the cursor is blinking inside the text field. There are functions for isFocused() and onFocus(), but how do I actually get the text field to give up focus. You would think it does so automatically once I hit enter, but that's not the case.

   import React, {Component} from 'react';
   import { AppRegistry, Text, View, StyleSheet, TextInput, TouchableOpacity} 
   from 'react-native';

   var SHA256 = require("crypto-js/sha256");

   export default class LoginForm extends Component{


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

tryLogin = () => {
    if(this.state.email=="email123" && this.state.password == "password"){
        console.log("password verified");
        this.props.navigator.replace({
            title: 'Dashboard'
        });
    }

    console.log(this.state.email);
    console.log(this.state.password);
    console.log("Hash" + SHA256(this.state.password));
}

render(){
    return(
        <View style={styles.container}>
            <TextInput 
                style={styles.input}

                placeholder="Email address" 
                placeholderTextColor="white"
                onChangeText={(email) => this.setState({email})}>
            </TextInput>
            <TextInput style={styles.input} 
                placeholder="Password" 
                placeholderTextColor="white" 
                secureTextEntry
                onChangeText={(password) => this.setState({password})}>
            </TextInput>

            <TouchableOpacity style={styles.loginButtonContainer} onPress={this.tryLogin}>
                <Text style={styles.loginButtonText}>LOGIN</Text>
            </TouchableOpacity>
        </View>
  );
}
}

AppRegistry.registerComponent('LoginForm', () => LoginForm);

const styles =  StyleSheet.create({
container: {
    padding: 20
},
input:{
    height: 40,
    backgroundColor: '#e74c3c',
    marginBottom: 20,
    color: 'white',
    paddingHorizontal: 15,
    opacity: .9
},
loginButtonContainer:{
    justifyContent: 'center',
    backgroundColor: '#bc4c3c',
    paddingVertical:15

},
loginButtonText:{
    textAlign:'center',
    color:'white',
    fontWeight: '700',
    fontSize: 24

}

   })

This probably won't matter as much for real users but I'm just emulating and its pesky if I want to reload.

5条回答
冷血范
2楼-- · 2020-06-06 20:40

Found it actually.It doesn't look as pretty and my intuition says this isn't a very "react" solution but if you want it here it is.

<TextInput 
 style={styles.input} 
 ref="email_input"
 onSubmitEditing={() => this.refs['email_input'].blur()} 
 placeholder="Email address" 
 placeholderTextColor="white"
 onChangeText={(email) => this.setState({email})}/>
查看更多
劳资没心,怎么记你
3楼-- · 2020-06-06 20:41

I managed to solve this with this.ref reference. First, you assign to the TextInput a ref, like this:

<input ref="myInput" />

Then, you call the blur() method to this.refs.myInput from a function

 blurTextInput(){
    this.refs.myInput.blur()
 }
查看更多
爱情/是我丢掉的垃圾
4楼-- · 2020-06-06 20:42

You can use Keyboard API.

import { Keyboard, TextInput } from 'react-native';

<TextInput
  onSubmitEditing={Keyboard.dismiss}
/>

Please see the full example in react native offical document.

查看更多
The star\"
5楼-- · 2020-06-06 20:42

Noah's answer above works well, but using string refs is now discouraged in React, and is likely going to be deprecated soon. Instead, you should use a callback function that gets called when the component you want to reference renders.

<TextInput 
  ref={(c: any) => {
    this.textInputRef = c;
  }}
  onSubmitEditing={() => this.textInputRef.blur()} 
/>

If you're using Flow, you can then specify the type of your ref by placing something like this outside of your render function:

textInputRef: ?TextInput;
查看更多
Juvenile、少年°
6楼-- · 2020-06-06 20:59

A better way is to use ScrollView and Keyboard.dismiss. By using ScrollView when the user taps outside of textInput, keyboard dismissed. It's done because ScrollView default property for keyboardShouldPersistTaps is never. It's the behavior the user expects. For dismiss the keyboard, or it's equivalent blur the textInput, when the user tap on the login button add Keyboard.dismissed() to the tryLogin function.

import React, {Component} from 'react';
import { AppRegistry, Text, View, StyleSheet, TextInput, TouchableOpacity, ScrollView, Keyboard}
  from 'react-native';
var SHA256 = require("crypto-js/sha256");

export default class LoginForm extends Component{


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

  tryLogin = () => {
    Keyboard.dismiss();
    if(this.state.email=="email123" && this.state.password == "password"){
      console.log("password verified");
      this.props.navigator.replace({
        title: 'Dashboard'
      });
    }

    console.log(this.state.email);
    console.log(this.state.password);
    console.log("Hash" + SHA256(this.state.password));
  }

  render(){
    return(
      <ScrollView style={styles.container}>
        <TextInput
          style={styles.input}

          placeholder="Email address"
          placeholderTextColor="white"
          onChangeText={(email) => this.setState({email})}>
        </TextInput>
        <TextInput style={styles.input}
                   placeholder="Password"
                   placeholderTextColor="white"
                   secureTextEntry
                   onChangeText={(password) => this.setState({password})}>
        </TextInput>

        <TouchableOpacity style={styles.loginButtonContainer} onPress={this.tryLogin}>
          <Text style={styles.loginButtonText}>LOGIN</Text>
        </TouchableOpacity>
      </ScrollView>
    );
  }
}

AppRegistry.registerComponent('LoginForm', () => LoginForm);

const styles =  StyleSheet.create({
  container: {
    padding: 20
  },
  input:{
    height: 40,
    backgroundColor: '#e74c3c',
    marginBottom: 20,
    color: 'white',
    paddingHorizontal: 15,
    opacity: .9
  },
  loginButtonContainer:{
    justifyContent: 'center',
    backgroundColor: '#bc4c3c',
    paddingVertical:15

  },
  loginButtonText:{
    textAlign:'center',
    color:'white',
    fontWeight: '700',
    fontSize: 24

  }

})
查看更多
登录 后发表回答