Martin Chinome
Martin Chinome

Reputation: 429

how get values of components react native

I want to get the value of the email and passowrd in my Form.js, so that click click button can pass them a client api 1. this is my class src/components/login/Form.js

        import React, { Component } from 'react';  
        import {
            KeyboardAvoidingView,
            StyleSheet,
            TouchableHighlight,
            Image,        
        } from 'react-native';
        import UserInput from "./UserInput";       
        import usernameImg from '../../images/Iconperson.png';
        import passwordImg from '../../images/Iconlock.png';
        import eyeImg  from '../../images/eye.png';       
            export default class Form extends Component {    
              constructor(props) {
            super(props);
            this.state = {
                    email: "",
                    password: "",
                };
        }  
        _onPress() {
           console.warn("email", this.state.email)
           console.warn("password", this.state.password)
      }  
          render() {
              return (
                  <KeyboardAvoidingView behavior='padding'
                    style={styles.container}>
                    <UserInput source={usernameImg}
                   onChangeText = {(email) => this.setState({email})}
                        keyboardType = 'email-address'
                        placeholder='Username'
                        autoCapitalize={'none'}
                        returnKeyType={'done'}
                        autoCorrect={false} />
                    <UserInput source={passwordImg}
                 onChangeText = {(password) => this.setState({password})}
                        placeholder='Password'
                        returnKeyType={'done'}
                        autoCapitalize={'none'}
                        autoCorrect={false} />
                    <TouchableHighlight
                        onPress={this._onPress}
                        activeOpacity={1} >
                        <Text>LOGIN</Text>
                    </TouchableHighlight>
                </KeyboardAvoidingView>

              );
          }
      }   
      const styles = StyleSheet.create({
        container: {
            flex: 1,
            alignItems: 'center',
        }
    });

2. this is my class src/components/login/UserInput.js

    import React, { Component , PropTypes} from 'react';
    import Dimensions from 'Dimensions';
    import {
    StyleSheet,
    View,
    TextInput,
    Image,
    } from 'react-native';  
    const DEVICE_WIDTH = Dimensions.get('window').width;
    const DEVICE_HEIGHT = Dimensions.get('window').height;

    export default class UserInput extends Component {
      render() {
          return (
              <View style={styles.inputWrapper}>
                <Image source={this.props.source}
                    style={styles.inlineImg} />
                <TextInput style={styles.input}
                    onChangeText = {(this.props.ChangeText) => 
                    this.setState({field})}
                    placeholder={this.props.placeholder}
                    secureTextEntry={this.props.secureTextEntry}
                    autoCorrect={this.props.autoCorrect}
                    autoCapitalize={this.props.autoCapitalize}
                    returnKeyType={this.props.returnKeyType}
                    placeholderTextColor='white'
                    keyboardType ={this.props.keyboardType}
                    underlineColorAndroid='transparent' />
            </View>

          );
      }
    }

    UserInput.propTypes = {
    ChangeText : PropTypes.string,
    source: PropTypes.number.isRequired,
    placeholder: PropTypes.string.isRequired,
    keyboardType : PropTypes.string,
    secureTextEntry: PropTypes.bool,
    autoCorrect: PropTypes.bool,
    autoCapitalize: PropTypes.string,
    returnKeyType: PropTypes.string,
    };
    const styles = StyleSheet.create({
    input: {
        backgroundColor: 'rgba(255, 255, 255, 0.2)',
        width: DEVICE_WIDTH - 40,
        height: 40,
        marginHorizontal: 20,
        paddingLeft: 45,
        borderRadius: 20,
        color: '#ffffff',
    },
    inputWrapper: {
        flex: 1,
    },
    inlineImg: {
        position: 'absolute',
        zIndex: 99,
        width: 22,
        height: 22,
        left: 35,
        top: 9,
    },
    });

Upvotes: 0

Views: 9277

Answers (2)

Adam Beleko
Adam Beleko

Reputation: 771

The value of TextInput may be retrieved through its _lastNativeTextproperty.

this.refs.myTextInput._lastNativeText

See this answer

Upvotes: 0

EJ Mason
EJ Mason

Reputation: 2050

As you are typing into the TextInput I see you are trying to change the state in the Form component. For this to happen correctly, setState needs to be called from the Form component. There are a couple functions currently being passed down through props:

(email) => this.setState({email})
// and
(password) => this.setState({password})

Looking at how those are being used in your UserInput component, whenever a new character is added to that text box, invoke the function above. so when this.setState() is called, it is saying UserInput.setState(). Since we want to change the state in Form we have to bind those functions to the parent component.

Instead of passing the functions directly to props, let's add some user methods:

export default class Form extends Component {
  constructor(props) {}

  _onChangeEmail(email) {
    this.setState(Object.assign({}, state, { email })); // good practice for immutability
  }

  _onChangePassword(password) {
    this.setState(Object.assign({}, state, { password })); // good practice for immutability
  }

  render() {}
}

Next, we need to bind these class methods to itself. That way no matter where these are called, this will always point to the Form component. This is most commonly done in the constructor:

export default class Form extends Component {
  constructor(props) {
    super(props)
    this.state = {}

    // this is where we do the binding
    this._onChangeEmail = this._onChangeEmail.bind(this)
    this._onChangePassword = this._onChangePassword.bind(this)
  }

  _onChangeEmail(email) { /* code */}

  _onChangePassword(password) { /* code */}

  render() {}
}

Now pass these down to the UserInput component through props:

// Form.js
render() {
  return (
    <KeyboardAvoidingView>
      <UserInput onChangeText={this._onChangeEmail} />
      <UserInput onChangeText={this._onChangePassword} />
    </KeyboardAvoidingView>
  )
}

These methods should now be used when the user inputs text:

export default class UserInput extends Component {
  render() {
    return (
      <View>
        <Image  />
          <TextInput onChangeText = {this.props.onChangeText} />
      </View>
    );
  }
}

Bonus: You also should add a property 'value' to the text input:

export default class UserInput extends Component {
  render() {
    return (
      <View>
        <Image  />
          <TextInput
            onChangeText={this.props.onChangeText} />
            value={this.props.textValue} 
      </View>
    );
  }
}

And make sure it is passed down from the parent component:

// Form.js
render() {
  return (
    <KeyboardAvoidingView>
      <UserInput
        onChangeText={this._onChangeEmail}
        textValue={this.state.email}/>
      <UserInput
        onChangeText={this._onChangePassword}
        textValue={this.state.password}/>
    </KeyboardAvoidingView>
  )
}

Upvotes: 4

Related Questions