SBB
SBB

Reputation: 8970

React Native - Calling a function

I am new to react-native but have been playing around with creating a simple login UI. I have a Login component and then two seperate form components for loginForm and forgotPasswordForm.

On my Login Component, I have a renderForm function that is trying to determine if we should show the loginForm or the forgotPasswordForm, which I assume would be based on state.

Login Component:

export default class Login extends Component {
  state = { 'display': '' };

  // Render the content
  renderForm(){
    // What page should show?
    switch(this.state.display){
      case 'forgotPasswordForm':
        return <ForgotPassword />;
      break;
      case 'loginForm':
        return <LoginForm />;
      break;
      default:
        return <LoginForm />;
      break;
    }
  }

  render() {
    return (
      <KeyboardAvoidingView behavior="padding" style={styles.container}>

        <View style={styles.logoContainer}>
          <Image
            style={styles.logo}
            source={require('../../images/logo.png')}
          />
          <Text style={styles.logoText}>Behavior Tracking System</Text>
        </View>

        <View style={styles.formContainer}>
          {this.renderForm()}
        </View>

      </KeyboardAvoidingView>
    );
  }
}

Here is my LoginForm which contains a link to the forgotPasswordFunction:

export default class LoginForm extends Component {

  forgotPasswordForm(){
    // Thought I could setState here so that the loginComponent would update and see the state and render the forgotPasswordForm instead
  }

  render() {
    return (
      <View style={styles.container}>
        <StatusBar
          barStyle="light-content"
        />
        <TextInput
          placeholder="username or email"
          placeholderTextColor="rgba(255,255,255,0.7)"
          returnKeyType="next"
          onSubmitEditing={() => this.passwordInput.focus()}
          keyboardType="email-address"
          autoCapitalize="none"
          autoCorrect={false}
          style={styles.input}
        />
        <TextInput
          placeholder="password"
          placeholderTextColor="rgba(255,255,255,0.7)"
          secureTextEntry={true}
          returnKeyType="go"
          style={styles.input}
          ref={(input) => this.passwordInput = input}
        />
        <TouchableOpacity style={styles.buttonContainer}>
          <Text style={styles.buttonText}>LOGIN</Text>
        </TouchableOpacity>
        <View style={styles.forgotPasswordContainer}>
          <Text style={styles.forgotPasswordText}>Trouble logging in? </Text>
          <TouchableOpacity onPress={this.forgotPasswordForm()}>
            <Text style={styles.activeLink}>Click Here.</Text>
          </TouchableOpacity>
        </View>
      </View>

    );
  }
}

I may be just a little confused at where some of this code should be placed. I assume since the LoginComponent is including the form fields itself, thats where I would put the switch logic to determine if we show the loginForm or forgotPasswordForm.

My issue is the onClick in the loginForm for the forgotPassword link. Not entirely sure how to get that to update the login component to switch forms.

enter image description here

My goal is that when the "Click Here" link is pressed, it loads the Password Recovery Field instead of the login fields.

Upvotes: 2

Views: 33573

Answers (1)

Matt Aft
Matt Aft

Reputation: 8936

Basically you need to create a function that will update the state in the parent component and pass it down to the child. Now if you call this.props.forgotPasswordForm() inside your LoginForm component, it will update the state in the parent and render the ForgotPassword component instead.

export default class Login extends Component {
  constructor(props) {
    super(props);
    this.state = { 
      display: 'loginForm' 
    }; //this is how  you set up state
  }

  // Render the content
  renderForm = () => {
    // What page should show?
    switch(this.state.display){
      case 'forgotPasswordForm':
        return <ForgotPassword />;
      break;
      case 'loginForm':
        return <LoginForm forgotPasswordForm={this.forgotPasswordForm} />; //pass method to child
      break;
      default:
        return <LoginForm forgotPasswordForm={this.forgotPasswordForm} />;
      break;
    }
  }
  // Create a function that will update the state in parent
  forgotPasswordForm = () => {
    this.setState({ display: 'forgotPasswordForm' });
  }

  render() {
    return (
      <KeyboardAvoidingView behavior="padding" style={styles.container}>

        <View style={styles.logoContainer}>
          <Image
            style={styles.logo}
            source={require('../../images/logo.png')}
          />
          <Text style={styles.logoText}>Behavior Tracking System</Text>
        </View>

        <View style={styles.formContainer}>
          {this.renderForm()}
        </View>

      </KeyboardAvoidingView>
    );
  }

Upvotes: 6

Related Questions