【问题标题】:react native get TextInput value反应原生获取 TextInput 值
【发布时间】:2015-12-31 00:40:32
【问题描述】:

我遇到了一个非常简单的问题。我有带有用户名、密码和按钮的登录表单。在我的按钮处理程序中,我尝试获取 textinput 值。但总是得到未定义的值。我错过了什么吗?

render() {
        <ExScreen
          headerColor={this.state.headerColor}
          scrollEnabled={this.state.enableScroll}
          style={styles.container} >
          <View >
            <View  >
              <View style={[styles.inputContainer]} >
                <TextInput
                  ref= "username"
                  onChangeText={(text) => this.setState({text})}
                  value={this.state.username}
                />
              </View>
 <Button style={{color: 'white', marginTop: 30, borderWidth: 1, borderColor: 'white', marginLeft: 20*vw, marginRight: 20*vw, height: 40, padding: 10}} 
             onPress={this._handlePress.bind(this)}>
              Sign In
            </Button>   
...
 _handlePress(event) {
    var username=this.refs.username.value;

【问题讨论】:

    标签: react-native


    【解决方案1】:

    快速且优化程度较低的方法是在 onChangeText 回调中使用箭头函数,在 onChangeText 回调中传递 username 作为参数。

    <TextInput
        ref= {(el) => { this.username = el; }}
        onChangeText={(username) => this.setState({username})}
        value={this.state.username}
    />
    

    然后在你的 _handlePress 方法中

    _handlePress(event) {
        let username=this.state.username;
    }
    

    但这有几个缺点!!!

    1. 每次渲染此组件时都会创建一个新的箭头函数。
    2. 如果子组件是 PureComponent,它将强制进行不必要的重新渲染,这会导致巨大的性能问题,尤其是在处理大量迭代的大型列表、表格或组件时。 More on this in React Docs

    最佳实践是使用类似handleInputChange 的处理程序并在构造函数中绑定```this``。

    ...
    constructor(props) {
      super(props);
      this.handleChange= this.handleChange.bind(this);
    }
    
    ...
    handleChange(event = {}) {
      const name = event.target && event.target.name;
      const value = event.target && event.target.value;
    
      this.setState([name]: value);
    }
    ...
    
    render() {
      ...
      <TextInput
        name="username"
        onChangeText={this.handleChange}
        value={this.state.username}
      />
      ...
    }
    
    ...
    

    或者,如果您使用自动绑定 this 的 es6 类属性简写。但这在测试和性能方面有缺点。 Read More Here

    ...
    handleChange= (event = {}) => {
      const name = event.target && event.target.name;
      const value = event.target && event.target.value;
    
      this.setState([name]: value);
    }
    ...
    
    render() {
      ...
      <TextInput
        name="username"
        onChangeText={this.handleChange}
        value={this.state.username}
      />
      ...
    }
    
    ...
    

    【讨论】:

    • 是的,我已经用声明 ref 的新方式更新了示例,但在此示例中,ref 并未真正使用,因此可以省略。
    • 我不知道为什么这会得到如此多的支持。在组件的渲染函数中设置状态不是不好的做法吗?
    • 我认为由于 setState 是在 onChangeText 回调中完成的,所以它是可以接受的,因为它没有在渲染块中被调用,我正在关注 react native text input example facebook.github.io/react-native/docs/textinput.html#examples ,也许他们是错???
    • 这不是一个优化的解决方案,因为您不想在每个更改文本上重新渲染整个组件..
    • 就我而言,我发现我必须将中间答案从 this.setState([name]: value); 更改为 this.setState({[name]: value}); 并将 value={this.state.username} 更改为 defaultValue={this.state.username}
    【解决方案2】:

    在 React Native 0.43 中:(可能晚于 0.43 也可以。)

    _handlePress(event) {
        var username= this.refs.username._lastNativeText;
    

    【讨论】:

    • 这似乎不完全符合您的需求。如果您在输入字段中输入“asdf”,并请求 _lastNatRiveText,我只得到“asd”。似乎有一个字符的延迟(总是错过 lastone)
    • 这行得通。感谢您实际回答问题。
    【解决方案3】:

    您应该使用 States 来存储输入字段的值。 https://facebook.github.io/react-native/docs/state.html

    • 要更新状态值,请使用setState

    onChangeText={(value) => this.setState({username: value})}

    • 并像这样获取输入值

    this.state.username

    示例代码

    export default class Login extends Component {
    
        state = {
            username: 'demo',
            password: 'demo'
        };
    
        <Text style={Style.label}>User Name</Text>
        <TextInput
            style={Style.input}
            placeholder="UserName"
            onChangeText={(value) => this.setState({username: value})}
            value={this.state.username}
        />
    
        <Text style={Style.label}>Password</Text>
        <TextInput
            style={Style.input}
            placeholder="Password"
            onChangeText={(value) => this.setState({password: value})}
            value={this.state.password}
        />
    
        <Button
            title="LOGIN"
            onPress={() => 
                {
                    if(this.state.username.localeCompare('demo')!=0){
                        ToastAndroid.show('Invalid UserName',ToastAndroid.SHORT);
                        return;
                    }
    
                    if(this.state.password.localeCompare('demo')!=0){
                        ToastAndroid.show('Invalid Password',ToastAndroid.SHORT);
                        return;
                    }
    
                    //Handle LOGIN
    
                }
            }
        />
    

    【讨论】:

      【解决方案4】:

      如果您像我一样不想使用或污染一次性组件的状态,这就是我所做的:

      import React from "react";
      import { Text, TextInput } from "react-native";
         
      export default class Registration extends Component {
        _register = () => {
          const payload = {
            firstName: this.firstName,
            /* other values */
          }
          
          console.log(payload)
        }
          
        render() {
          return (
            <RegisterLayout>
              <Text style={styles.welcome}>
                Register
              </Text>
      
              <TextInput
                placeholder="First Name"
                onChangeText={(text) => this.firstName = text} />
      
              {/*More components...*/}
      
              <CustomButton
                backgroundColor="steelblue"
                handlePress={this._register}>
                Submit
              </CustomButton>
           </RegisterLayout>
          )
        }
      }
      

      【讨论】:

      • 我喜欢这个,似乎工作,看起来不是超级hacky,并且不需要参考或状态。
      • InputTextTextInput 我猜,还是我错过了什么?
      • 这是展示不受控制的输入方法的少数示例之一。我喜欢它,因为每次输入更改时调用setState 不会导致不必要的重新渲染。如果您不需要为每次更改做一些特殊的事情,而只需要按下“提交”按钮时的文本值,这是正确的方法。
      【解决方案5】:

      export default class App extends Component {
        state = { username: '', password: '' }
      
        onChangeText = (key, val) => {
          this.setState({ [key]: val})
        }
        
        render() { 
          return (
            <View style={styles.container}>
                <Text>Login Form</Text>
                <TextInput
                  placeholder='Username'
                  onChangeText={val => this.onChangeText('username', val)}
                  style={styles.input}
                />
                <TextInput
                  placeholder='Password'
                  onChangeText={val => this.onChangeText('password', val)}
                  style={styles.input}
                  secureTextEntry={true}
                />      
            </View>
          );
        }
      }

      希望这能解决您的问题

      【讨论】:

      • 欢迎来到 SO。发布答案时,仅提供代码是没有帮助的。重要的是要解释你的代码做什么以及它如何解决手头的问题:)
      • 参考?裁判呢?
      【解决方案6】:

      这对我有用

          <Form>
      
          <TextInput
          style={{height: 40}}
          placeholder="userName"
          onChangeText={(text) => this.userName = text}
          />
      
          <TextInput
          style={{height: 40}}
          placeholder="Password"
          onChangeText={(text) => this.Password = text}
          />
      
      
          <Button 
          title="Sign in!" 
          onPress={this._signInAsync} 
          />
      
          </Form>
      

        _signInAsync = async () => {
              console.log(this.userName)
              console.log(this.Password) 
        };
      

      【讨论】:

      • 这很好用! +1 不搞乱状态
      【解决方案7】:

      请注意如何使用 setState()。正确的形式是

      this.setState({
            Key: Value,
          });
      

      所以我会这样做:

      onChangeText={(event) => this.setState({username:event.nativeEvent.text})}
      ...    
      var username=this.state.username;
      

      【讨论】:

      • 如果上面的方法不行,试试这个:onChangeText={(event) => this.setState({username: event.nativeEvent.text})
      • 我得到'未定义不是一个对象(评估 event.nativeEvent.text)'
      • .. 但是,如果我使用 onChange 事件而不是 onChangeText 事件,它确实有效
      • 使用 ES6,如果键和值是 foo,你可以写 this.setState({ foo }),更多在这里:es6-features.org/#PropertyShorthand 所以在上面的例子中这是正确的onChangeText={(username) =&gt; this.setState({username})}
      • onChange 接收事件对象作为其参数,而onChangeText 接收更改后的文本字符串作为其参数。
      【解决方案8】:

      尝试控制台记录对象,您将在 nativeEvent.text 中找到您输入的文本

      示例:

      handelOnChange = (enteredText) => {
          console.log(enteredText.nativeEvent.text)
      }
      render()
      return (
          <SafeAreaView>
              <TextInput
                  onChange={this.handelOnChange}
              >
      </SafeAreaView>
      
      )
      

      【讨论】:

        【解决方案9】:
        constructor(props) {
                super(props);
        
                this.state ={
                    commentMsg: ''         
                }
            }
        
         onPress = () => {
                  alert("Hi " +this.state.commentMsg)
              }
        
         <View style={styles.sendCommentContainer}>
        
             <TextInput
                style={styles.textInput}
                multiline={true}
                onChangeText={(text) => this.setState({commentMsg: text})}
                placeholder ='Comment'/>
        
               <Button onPress={this.onPress} 
                   title="OK!"
                   color="#841584"
                />
        
          </TouchableOpacity>
        
        </View>
        

        【讨论】:

          【解决方案10】:

          简单地做。

          this.state={f_name:""};
          
          textChangeHandler = async (key, val) => {
              await this.setState({ [key]: val });
          }
          
          <Textfield onChangeText={val => this.textChangeHandler('f_name', val)}>
          

          【讨论】:

            【解决方案11】:

            通过这个程序,一切对我来说都很好:

            <Input onChangeText={this.inputOnChangeText} />
            

            还有:

            inputOnChangeText = (e) => {
              this.setState({
                username: e
              })
            }
            

            【讨论】:

              【解决方案12】:

              React Native Latest -> 使用基于状态的方法的简单易用的解决方案。

              const [userEmail, setUserEmail] = useState(""); 
              
              <TextInput
                        value={userEmail}
                        style={styles.textInputStyle}
                        placeholder="Email"
                        placeholderTextColor="steelblue"
                        onChangeText={(userEmail) => setUserEmail(userEmail)}
                      />
              

              【讨论】:

                【解决方案13】:

                如果你设置了文本状态,为什么不直接使用呢?

                _handlePress(event) {
                  var username=this.state.text;
                

                当然,变量命名可能比“文本”更具描述性,但您可以自己调用。

                【讨论】:

                  【解决方案14】:

                  onChange&lt;TextInput /&gt;onTextChange 属性之间存在巨大差异。不要像我一样使用返回stringonTextChange,不要使用返回完整对象的onChange

                  花 1 个小时来弄清楚我的价值在哪里,我感到很愚蠢。

                  【讨论】:

                    【解决方案15】:

                    您不需要为 taht 创建新功能。 只需创建一个新的 useState 并在 onchange 中使用它。

                    const UselessTextInput = () => {
                      const [text, onChangeText] = React.useState("Useless Text");
                      const [number, onChangeNumber] = React.useState(null);
                    
                      return (
                        <SafeAreaView>
                          <TextInput
                            style={styles.input}
                            onChangeText={onChangeText}
                            value={text}
                          />
                          <TextInput
                            style={styles.input}
                            onChangeText={onChangeNumber}
                            value={number}
                            placeholder="useless placeholder"
                            keyboardType="numeric"
                          />
                        </SafeAreaView>
                      );
                    };
                    

                    【讨论】:

                      【解决方案16】:

                      这段代码对我有用。我缺少的是我没有在按钮操作中传递“this”:

                       onPress={this._handlePress.bind(this)}>
                      --------------
                      
                        _handlePress(event) {
                      console.log('Pressed!');
                      
                       var username = this.state.username;
                       var password = this.state.password;
                      
                       console.log(username);
                       console.log(password);
                      }
                      
                        render() {
                          return (
                            <View style={styles.container}>
                      
                            <TextInput
                            ref="usr"
                            style={{height: 40, borderColor: 'gray', borderWidth: 1 , marginTop: 10 , padding : 10 , marginLeft : 5 , marginRight : 5 }}
                            placeHolder= "Enter username "
                            placeholderTextColor = '#a52a2a'
                      
                            returnKeyType = {"next"}
                            autoFocus = {true}
                            autoCapitalize = "none"
                            autoCorrect = {false}
                            clearButtonMode = 'while-editing'
                            onChangeText={(text) => {
                                this.setState({username:text});
                              }}
                            onSubmitEditing={(event) => {
                           this.refs.psw.focus();
                      
                            }}
                            />
                      
                            <TextInput
                            ref="psw"
                            style={{height: 40, borderColor: 'gray', borderWidth: 1 , marginTop: 10,marginLeft : 5 , marginRight : 5}}
                            placeholder= "Enter password"
                            placeholderTextColor = '#a52a2a'
                            autoCapitalize = "none"
                            autoCorrect = {false}
                            returnKeyType = {'done'}
                            secureTextEntry = {true}
                            clearButtonMode = 'while-editing'
                            onChangeText={(text) => {
                                this.setState({password:text});
                              }}
                            />
                      
                            <Button
                              style={{borderWidth: 1, borderColor: 'blue'}}
                              onPress={this._handlePress.bind(this)}>
                              Login
                            </Button>
                      
                            </View>
                          );``
                        }
                      }
                      

                      【讨论】:

                        【解决方案17】:

                        类初始化中的用户:

                        constructor() {
                            super()
                            this.state = {
                                email: ''
                            }
                        }
                        

                        然后在某个函数中:

                        handleSome = () => { console.log(this.state.email) };

                        在输入中:

                        <TextInput onChangeText={(email) => this.setState({email})}/>

                        【讨论】:

                          【解决方案18】:

                          你试过了吗

                          var username=this.state.username;
                          

                          【讨论】:

                          • 这是个坏主意。你应该总是像 @andreaswienes 那样使用 this.setState({...})。
                          猜你喜欢
                          • 1970-01-01
                          • 1970-01-01
                          • 2017-02-06
                          • 1970-01-01
                          • 1970-01-01
                          • 2017-04-08
                          • 2018-09-16
                          • 1970-01-01
                          • 2021-08-20
                          相关资源
                          最近更新 更多