【问题标题】:Unfocus a TextInput in React Native在 React Native 中取消焦点文本输入
【发布时间】:2017-09-11 21:57:57
【问题描述】:

我正在使用 React Native 构建一个 Android 应用。

如何强制TextInput 为“unFocus”,这意味着光标在文本字段内闪烁。有isFocused()onFocus() 的功能,但我实际上如何让文本字段放弃焦点。您会认为一旦我按 Enter 键,它就会自动执行此操作,但事实并非如此。

   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

}

   })

这对于真实用户来说可能并不重要,但我只是在模拟,如果我想重新加载它会很烦人。

【问题讨论】:

  • 仅使用散列函数是不够的,仅添加盐对提高安全性无济于事。相反,iIterate over an HMAC with a random salt for about 100ms duration and save the salt with the hash.使用PBKDF2Rfc2898DeriveBytespassword_hashBcrypt 等函数或类似函数。关键是让攻击者花费大量时间通过蛮力寻找密码。

标签: android react-native focus user-input react-native-android


【解决方案1】:

更好的方法是使用 ScrollViewKeyboard.dismiss。当用户在 textInput 之外点击时使用 ScrollView,键盘会被关闭。这样做是因为 ScrollView 的默认属性 keyboardShouldPersistTapsnever。这是用户期望的行为。为了关闭键盘,或者等效地模糊 textInput,当用户点击登录按钮时,将 Keyboard.dismissed() 添加到 tryLogin功能。

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

  }

})

【讨论】:

    【解决方案2】:

    您可以使用 Keyboard API。

    import { Keyboard, TextInput } from 'react-native';
    
    <TextInput
      onSubmitEditing={Keyboard.dismiss}
    />
    

    请参阅react native offical document 中的完整示例。

    【讨论】:

    • onSubmitEditing 是我想要的。当用户按下键盘上的nextdone 图标时,将调用此函数。
    【解决方案3】:

    我设法通过 this.ref 参考解决了这个问题。 首先,为 TextInput 分配一个 ref,如下所示:

    <input ref="myInput" />
    

    然后,你从一个函数调用 blur() 方法到this.refs.myInput

     blurTextInput(){
        this.refs.myInput.blur()
     }
    

    【讨论】:

    • ref="myInput" 已弃用。而是使用 ref={(ref) => { this.myInput= ref }} 并用作 this.myInput.focus() 或 this.myInput.blur()
    【解决方案4】:

    确实找到了。它看起来不那么漂亮,我的直觉说这不是一个非常“反应”的解决方案,但如果你想要它就在这里。

    <TextInput 
     style={styles.input} 
     ref="email_input"
     onSubmitEditing={() => this.refs['email_input'].blur()} 
     placeholder="Email address" 
     placeholderTextColor="white"
     onChangeText={(email) => this.setState({email})}/>
    

    【讨论】:

      【解决方案5】:

      我的用例有点不同。用户不会直接在输入字段中输入值。该字段主要用于捕获用户输入值的尝试并改为打开模式。我想在模态关闭后模糊该字段,以减少用户稍后必须做的额外点击。

      如果使用 Hooks,你可以做一些简单的事情

      const inputRef = useRef(null);
      
      <Input
        ref={inputRef}
        {...props}
      />
      

      然后在任何你需要的地方调用它。

      inputRef.current.blur();
      

      【讨论】:

      • 这个答案拯救了我的一天。谢谢
      • 和我一样。我认识到更好的方式是文本组件设置可编辑的 false 和文本组件由视图或可触摸组件包装
      【解决方案6】:

      Noah's answer above 效果很好,但使用字符串引用是now discouraged in React,并且很可能很快就会被弃用。相反,您应该使用一个回调函数,该函数在您要引用的组件呈现时被调用。

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

      如果您使用的是 Flow,则可以通过在渲染函数之外放置类似这样的内容来指定 ref 的类型:

      textInputRef: ?TextInput;
      

      【讨论】:

        【解决方案7】:

        如果您想在提交后失去焦点,请使用 blurOnSubmit 属性。

        <TextInput 
           blurOnSubmit={true}
           //other props
        />
        

        【讨论】:

        • 嗨,Darkleon,欢迎来到 SO,请为您的答案提供更多详细信息以及如何执行此操作的实际示例。谢谢
        【解决方案8】:

        它做它需要的东西

        function TextInputCustom({ placeholder, style }) {
        
            React.useEffect(() => {
                const keyboardHide = Keyboard.addListener('keyboardDidHide', () => {
                    Keyboard.dismiss();
                });
                return () => {
                    keyboardHide.remove()
                }
            }, []);
            return (
                <TextInput
                    style={style}
                    placeholder={placeholder}            
                />
            )
        }
        
        export default TextInputCustom;
        

        【讨论】:

        • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
        猜你喜欢
        • 1970-01-01
        • 2019-07-04
        • 1970-01-01
        • 2021-08-27
        • 2022-06-10
        • 1970-01-01
        • 2021-10-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多