Ad

React Native Is Ignoring State Change

Please explain why this isn't working. I am trying to replace one element with another on a button press in React, and, according to all documentation, what I am doing should work. However, React is entirely ignoring state changes and refusing to re-render an element. Here is my file:

import React, {Component} from 'react';
import {View, Text, TextInput, TouchableOpacity} from 'react-native';
import styles from '../styles';
import User from '../models/User';
export default class SignIn extends Component {
    constructor(props){
        super(props);
        this.state = {
            email: '',
            password: '',
            signIn: '',
            errorMessage: null,
            signUp: true
        }
    }
    signIn(){
        var err = e => this.setState({errorMessage: e.message});
        var next = u => this.props.navigation.push('Details');
        User.login(this.state.email, this.state.password, err, next);
    }
    signUp(){
        var err = e => this.setState({errorMessage: e.message});
        var next = _ => this.props.navigation.push('Details');
        var user = new User(this.state.email, this.state.password);
        user.save(err, next);
    }
    render(){
        return (
            <View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
                <View style={{flexDirection: 'row', width: 300, justifyContent: 'center'}}>
                    <TouchableOpacity onPress={_ => this.setState({signUp: true})} style={[styles.navButton, styles.tabsButton]}>
                        <Text style={[styles.buttonText, styles.tabs]}>Sign Up</Text>
                    </TouchableOpacity>
                    <TouchableOpacity onPress={_ => this.setState({signUp: false})} style={[styles.grey, styles.tabsButton]}>
                        <Text style={[styles.greyText, styles.tabs]}>Sign In</Text>
                    </TouchableOpacity>
                </View>
                {this.state.signUp && <View>
                    <Text style={{color: 'red'}}>{this.state.errorMessage}</Text>
                    <TextInput 
                        placeholder={'Email'} 
                        style={styles.input} 
                        value={this.state.email} 
                        onChangeText={(email) => this.setState({email})}
                    />
                    <TextInput 
                        placeholder={'Password'} 
                        style={styles.input} 
                        secureTextEntry={true} 
                        onChangeText={(password) => this.setState({password})}
                    />
                    <TouchableOpacity style={styles.navButton}>
                        <Text style={styles.buttonText}>Sign Up</Text>
                    </TouchableOpacity>      
                </View>}  
                {!this.state.signUp && <View>
                    <Text style={{color: 'red'}}>{this.state.errorMessage}</Text>
                    <TextInput 
                        placeholder={'Email'} 
                        style={styles.input} 
                        value={this.state.email} 
                        onChangeText={(email) => this.setState({email})}
                    />
                    <TextInput 
                        placeholder={'Password'} 
                        style={styles.input} 
                        secureTextEntry={true} 
                        onChangeText={(password) => this.setState({password})}
                    />
                    <TouchableOpacity style={[styles.navButton]}>
                        <Text style={styles.buttonText}>Sign Up</Text>
                    </TouchableOpacity>       
                </View>}
            </View>
        )
    }
}

The Sign In button at the top should change the state and cause a Sign In form to appear and the Sign Up form to disappear, while the Sign Up button should do the opposite. If I console.log the state after the change, it has changed, but nothing else happens. What is going on? All documentation shows that you can do this, but it doesn't work for me. I am running the app on an Android phone over Expo.

Ad

Answer

{this.state.signUp 
  ? <View>
      <Text style={{color: 'red'}}>{this.state.errorMessage}</Text>
      <TextInput 
          placeholder={'Email'} 
          style={styles.input} 
          value={this.state.email} 
          onChangeText={(email) => this.setState({email})}
      />
      <TextInput 
          placeholder={'Password'} 
          style={styles.input} 
          secureTextEntry={true} 
          onChangeText={(password) => this.setState({password})}
      />
      <TouchableOpacity style={styles.navButton}>
          <Text style={styles.buttonText}>Sign Up</Text>
      </TouchableOpacity>      
    </View>  
  : <View>
      <Text style={{color: 'red'}}>{this.state.errorMessage}</Text>
      <TextInput 
          placeholder={'Email'} 
          style={styles.input} 
          value={this.state.email} 
          onChangeText={(email) => this.setState({email})}
      />
      <TextInput 
          placeholder={'Password'} 
          style={styles.input} 
          secureTextEntry={true} 
          onChangeText={(password) => this.setState({password})}
      />
      <TouchableOpacity style={[styles.navButton]}>
          <Text style={styles.buttonText}>Sign Up</Text>
      </TouchableOpacity>       
    </View>
}

If this wouldn't work, maybe styles?

Ad
source: stackoverflow.com
Ad