2 votes

React native state.token est indéfini

J'ai créé un backend qui génère un jeton web json qui identifie l'utilisateur.

enter image description here

Mais lorsque je passe à l'écran suivant, le jeton est indéfini. Qu'est-ce que je fais de mal ?

Le régler :

  fetch('https://www.koolbusiness.com/account/mob_login', {
      method: 'POST',
      headers: {
          Accept: 'application/json',
          'Content-Type': 'application/json',
      },
      body: JSON.stringify({
          "email": this.state.email,
          "password": this.state.password,
      }),
  }).then((response) => response.json())
      .then((responseJson) => {
          this.state.token = responseJson.token;

En essayant de l'utiliser dans l'écran suivant, il est alors indéfini.

Écran de connexion :

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import {
  StyleSheet,
  View,
  Text,Alert,
  ImageBackground,
  Dimensions,
  LayoutAnimation,
  UIManager,
  KeyboardAvoidingView,
} from 'react-native';
//import { Font } from 'expo';
import { Input, Button } from 'react-native-elements'

import Icon from 'react-native-vector-icons/FontAwesome';
import SimpleIcon from 'react-native-vector-icons/SimpleLineIcons';

const SCREEN_WIDTH = Dimensions.get('window').width;
const SCREEN_HEIGHT = Dimensions.get('window').height;

const BG_IMAGE = require('../../../assets/images/bg_screen4.jpg');

// Enable LayoutAnimation on Android
UIManager.setLayoutAnimationEnabledExperimental
  && UIManager.setLayoutAnimationEnabledExperimental(true);

const TabSelector = ({ selected }) => {
  return (
    <View style={styles.selectorContainer}>
      <View style={selected && styles.selected}/>
    </View>
  );
};

TabSelector.propTypes = {
  selected: PropTypes.bool.isRequired,
};
let self;
export default class LoginScreen2 extends Component {

  constructor(props) {
    super(props);

    this.state = {
      email: '',
      password: '',
      fontLoaded: false,
      selectedCategory: 0,
      isLoading: false,
      isEmailValid: true,
      isPasswordValid: true,
      isConfirmationValid: true,
    };

    this.selectCategory = this.selectCategory.bind(this);
    this.login = this.login.bind(this);
    this.signUp = this.signUp.bind(this);
      self = this;
  }

  async componentDidMount() {
   // await Font.loadAsync({
    //  'georgia': require('../../../assets/fonts/Georgia.ttf'),
     // 'regular': require('../../../assets/fonts/Montserrat-Regular.ttf'),
      //'light': require('../../../assets/fonts/Montserrat-Light.ttf'),
    //});

    this.setState({ fontLoaded: true });
  }

  selectCategory(selectedCategory) {
    LayoutAnimation.easeInEaseOut();
    this.setState({
      selectedCategory,
      isLoading: false,
    });
  }

  validateEmail(email) {
    var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;

    return re.test(email);
  }

  login() {
    const {
      email,
      password,
        token
    } = this.state;

      fetch('https://www.koolbusiness.com/account/mob_login', {
          method: 'POST',
          headers: {
              Accept: 'application/json',
              'Content-Type': 'application/json',
          },
          body: JSON.stringify({
              "email": this.state.email,
              "password": this.state.password,
          }),
      }).then((response) => response.json())
          .then((responseJson) => {
              self.setState({token:responseJson.token});
            //  this.state.token = responseJson.token;
              this.props.state = this.state;

              Alert.alert(
                  'Welcome',
                  'You are now logged in',
                  [
                      {text: responseJson.token, onPress: () => console.log('Ask me later pressed')},
                      {text: 'Cancel', onPress: () => console.log('Cancel Pressed'), style: 'cancel'},
                      {text: 'OK', onPress: () => console.log('OK Pressed')},
                  ],
                  { cancelable: false }
              );
          })
          .catch((error) => {
              console.error(error);
          });

    //this.setState({ isLoading: true });
    // Simulate an API call
    //setTimeout(() => {
    //  LayoutAnimation.easeInEaseOut();
    //  this.setState({
    //    isLoading: false,
    //    isEmailValid: this.validateEmail(email) || this.emailInput.shake(),
    //    isPasswordValid: password.length >= 8 || this.passwordInput.shake(),
    //  });
    //}, 1500);

  }

  signUp() {
    const {
      email,
      password,
      passwordConfirmation,
    } = this.state;
    this.setState({ isLoading: true });
    // Simulate an API call
    setTimeout(() => {
      LayoutAnimation.easeInEaseOut();
      this.setState({
        isLoading: false,
        isEmailValid: this.validateEmail(email) || this.emailInput.shake(),
        isPasswordValid: password.length >= 8 || this.passwordInput.shake(),
        isConfirmationValid: password == passwordConfirmation || this.confirmationInput.shake(),
      });
    }, 1500);
  }

  render() {
    const {
      selectedCategory,
      isLoading,
      isEmailValid,
      isPasswordValid,
      isConfirmationValid,
      email,
      password,
      passwordConfirmation,
    } = this.state;
    const isLoginPage = selectedCategory === 0;
    const isSignUpPage = selectedCategory === 1;
      return (
          <View style={styles.container}>
              <ImageBackground
                  source={BG_IMAGE}
                  style={styles.bgImage}
              >
                  {this.state.fontLoaded ?
                      <View>
                          <KeyboardAvoidingView contentContainerStyle={styles.loginContainer} behavior='position'>
                              <View style={styles.titleContainer}>
                                  <View style={{flexDirection: 'row'}}>
                                      <Text style={styles.titleText}>Login</Text>
                                  </View>
                                  <View style={{marginTop: -10, marginLeft: 10}}>
                                      <Text style={styles.titleText}>or Sign Up</Text>
                                  </View>
                              </View>
                              <View style={{flexDirection: 'row'}}>
                                  <Button
                                      disabled={isLoading}
                                      clear
                                      activeOpacity={0.7}
                                      onPress={() => this.selectCategory(0)}
                                      containerStyle={{flex: 1}}
                                      titleStyle={[styles.categoryText, isLoginPage && styles.selectedCategoryText]}
                                      title={'Login'}
                                  />
                                  <Button
                                      disabled={isLoading}
                                      clear
                                      activeOpacity={0.7}
                                      onPress={() => this.selectCategory(1)}
                                      containerStyle={{flex: 1}}
                                      titleStyle={[styles.categoryText, isSignUpPage && styles.selectedCategoryText]}
                                      title={'Sign up'}
                                  />
                              </View>
                              <View style={styles.rowSelector}>
                                  <TabSelector selected={isLoginPage}/>
                                  <TabSelector selected={isSignUpPage}/>
                              </View>
                              <View style={styles.formContainer}>
                                  <Input
                                      icon={
                                          <Icon
                                              name='envelope-o'
                                              color='rgba(0, 0, 0, 0.38)'
                                              size={25}
                                              style={{backgroundColor: 'transparent'}}
                                          />
                                      }
                                      value={email}
                                      keyboardAppearance='light'
                                      autoFocus={false}
                                      autoCapitalize='none'
                                      autoCorrect={false}
                                      keyboardType='email-address'
                                      returnKeyType='next'
                                      inputStyle={{marginLeft: 10}}
                                      placeholder={'Email'}
                                      containerStyle={{borderBottomColor: 'rgba(0, 0, 0, 0.38)'}}
                                      ref={input => this.emailInput = input}
                                      onSubmitEditing={() => this.passwordInput.focus()}
                                      onChangeText={email => this.setState({ email })}
                                      displayError={!isEmailValid}
                                      errorMessage='Please enter a valid email address'
                                  />
                                  <Input
                                      icon={
                                          <SimpleIcon
                                              name='lock'
                                              color='rgba(0, 0, 0, 0.38)'
                                              size={25}
                                              style={{backgroundColor: 'transparent'}}
                                          />
                                      }
                                      value={password}
                                      keyboardAppearance='light'
                                      autoCapitalize='none'
                                      autoCorrect={false}
                                      secureTextEntry={true}
                                      returnKeyType={isSignUpPage ? 'next' : 'done'}
                                      blurOnSubmit={true}
                                      containerStyle={{marginTop: 16, borderBottomColor: 'rgba(0, 0, 0, 0.38)'}}
                                      inputStyle={{marginLeft: 10}}
                                      placeholder={'Password'}
                                      ref={input => this.passwordInput = input}
                                      onSubmitEditing={() => isSignUpPage ? this.confirmationInput.focus() : this.login()}
                                      onChangeText={(password) => this.setState({password})}
                                      displayError={!isPasswordValid}
                                      errorMessage='Please enter at least 8 characters'
                                  />
                                  {isSignUpPage &&
                                  <Input
                                      icon={
                                          <SimpleIcon
                                              name='lock'
                                              color='rgba(0, 0, 0, 0.38)'
                                              size={25}
                                              style={{backgroundColor: 'transparent'}}
                                          />
                                      }
                                      value={passwordConfirmation}
                                      secureTextEntry={true}
                                      keyboardAppearance='light'
                                      autoCapitalize='none'
                                      autoCorrect={false}
                                      keyboardType='default'
                                      returnKeyType={'done'}
                                      blurOnSubmit={true}
                                      containerStyle={{marginTop: 16, borderBottomColor: 'rgba(0, 0, 0, 0.38)'}}
                                      inputStyle={{marginLeft: 10}}
                                      placeholder={'Confirm password'}
                                      ref={input => this.confirmationInput = input}
                                      onSubmitEditing={this.signUp}
                                      onChangeText={passwordConfirmation => this.setState({ passwordConfirmation })}
                                      displayError={!isConfirmationValid}
                                      errorMessage='Please enter the same password'
                                  />}
                                  <Button
                                      buttonStyle={styles.loginButton}
                                      containerStyle={{marginTop: 32, flex: 0}}
                                      activeOpacity={0.8}
                                      title={isLoginPage ? 'LOGIN' : 'SIGN UP'}
                                      onPress={isLoginPage ? this.login : this.signUp}
                                      titleStyle={styles.loginTextButton}
                                      loading={isLoading}
                                      disabled={isLoading}
                                  />
                              </View>
                          </KeyboardAvoidingView>
                          <View style={styles.helpContainer}>
                              <Button
                                  title={'Need help ?'}
                                  titleStyle={{color: 'white'}}
                                  buttonStyle={{backgroundColor: 'transparent'}}
                                  underlayColor='transparent'
                                  onPress={() => console.log('Account created')}
                              />
                          </View>
                      </View>
                      :
                      <Text>Loading...</Text>
                  }
              </ImageBackground>
          </View>
      );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  rowSelector: {
    height: 20,
    flexDirection: 'row',
    alignItems: 'center',
  },
  selectorContainer: {
    flex: 1,
    alignItems: 'center',
  },
  selected: {
    position: 'absolute',
    borderRadius: 50,
    height: 0,
    width: 0,
    top: -5,
    borderRightWidth: 70,
    borderBottomWidth: 70,
    borderColor: 'white',
    backgroundColor: 'white',
  },
  loginContainer: {
    alignItems: 'center',
    justifyContent: 'center',
  },
  loginTextButton: {
    fontSize: 16,
    color: 'white',
    fontWeight: 'bold',
  },
  loginButton: {
    backgroundColor: 'rgba(232, 147, 142, 1)',
    borderRadius: 10,
    height: 50,
    width: 200,
  },
  titleContainer: {
    height: 150,
    backgroundColor: 'transparent',
    justifyContent: 'center',
  },
  formContainer: {
    backgroundColor: 'white',
    width: SCREEN_WIDTH - 30,
    borderRadius: 10,
    paddingTop: 32,
    paddingBottom: 32,
    alignItems:'center',
  },
  loginText: {
    fontSize: 16,
    fontWeight: 'bold',
    color: 'white',
  },
  bgImage: {
    flex: 1,
    top: 0,
    left: 0,
    width: SCREEN_WIDTH,
    height: SCREEN_HEIGHT,
    justifyContent: 'center',
    alignItems: 'center',
  },
  categoryText: {
    textAlign: 'center',
    color: 'white',
    fontSize: 24,

    backgroundColor: 'transparent',
    opacity: 0.54,
  },
  selectedCategoryText: {
    opacity: 1,
  },
  titleText: {
    color: 'white',
    fontSize: 30,

  },
  helpContainer: {
    height: 64,
    alignItems: 'center',
    justifyContent: 'center',
  },
});

Écran suivant

import React, { Component } from 'react';
import {
    StyleSheet, Text, View, Image, ScrollView, Dimensions, TouchableOpacity, StatusBar, Alert
} from 'react-native';
import { Button } from 'react-native-elements'

const SCREEN_WIDTH = Dimensions.get('window').width;
const SCREEN_HEIGHT = Dimensions.get('window').height;

const IMAGE_SIZE = SCREEN_WIDTH - 80;

class CustomButton extends Component {
    constructor() {
        super();

        this.state = {
            selected: false
        };
    }

    componentDidMount() {
        const { selected } = this.props;

        this.setState({
            selected
        });
    }

    render() {
        const { title } = this.props;
        const { selected } = this.state;

        return (
            <Button
                title={title}
                titleStyle={{ fontSize: 15, color: 'white' }}
                buttonStyle={selected ? { backgroundColor: 'rgba(213, 100, 140, 1)', borderRadius: 100, width: 127 } : { borderWidth: 1, borderColor: 'white', borderRadius: 30, width: 127, backgroundColor: 'transparent' }}
                containerStyle={{ marginRight: 10 }}
                onPress={() => this.setState({ selected: !selected })}
            />
        );
    }
}

export default class LoginScreen1 extends Component {
    constructor(props) {
        super(props);

        this.state = {

            fontLoaded: false,
        };
    }

    async componentDidMount() {

       this.setState({ fontLoaded: true });
    }

    render() {

        Alert.alert(
            'Token '+this.state.token,
            'You are now logged in',
            [
                {text: this.state.token, onPress: () => console.log('Ask me later pressed')},
                {text: 'Cancel', onPress: () => console.log('Cancel Pressed'), style: 'cancel'},
                {text: 'OK', onPress: () => console.log('OK Pressed')},
            ],
            { cancelable: false }
        );

        return (
            <View style={{flex: 1}}>
                <StatusBar
                    barStyle="light-content"
                />
                { this.state.fontLoaded ?
                    <View style={{flex: 1, backgroundColor: 'rgba(47,44,60,1)'}}>
                        <View style={styles.statusBar} />
                        <View style={styles.navBar}>
                            <Text style={styles.nameHeader}>
                                Johanna Bloggs, 26
                            </Text>
                        </View>
                        <ScrollView style={{flex: 1}}>
                            <View style={{ justifyContent: 'center', alignItems: 'center' }}>
                                <Image
                                    source={{ uri: 'https://static.pexels.com/photos/428336/pexels-photo-428336.jpeg' }}
                                    style={{ width: IMAGE_SIZE, height: IMAGE_SIZE, borderRadius: 10}}
                                />
                            </View>
                            <View style={{flex: 1, flexDirection: 'row', marginTop: 20, marginHorizontal: 40, justifyContent: 'center', alignItems: 'center'}}>
                                <Text style={{flex: 1, fontSize: 26, color: 'white'}}>
                                    Johanna Bloggs {this.state.email}
                                </Text>
                                <Text style={{flex: 0.5, fontSize: 15, color: 'gray', textAlign: 'left', marginTop: 5}}>
                                    0.8 mi
                                </Text>
                                <Text style={{flex: 1, fontSize: 26, color: 'green', textAlign: 'right'}}>
                                    84%
                                </Text>
                            </View>
                            <View style={{flex: 1, marginTop: 20, width: SCREEN_WIDTH - 80, marginLeft: 40}}>
                                <Text style={{flex: 1, fontSize: 15, color: 'white'}}>
                                    100% Italian, fun loving, affectionate, young lady who knows what it takes to make a relationship work.
                                </Text>
                            </View>
                            <View style={{flex: 1, marginTop: 30}}>
                                <Text style={{flex: 1, fontSize: 15, color: 'rgba(216, 121, 112, 1)',  marginLeft: 40}}>
                                    INTERESTS
                                </Text>
                                <View style={{flex: 1, width: SCREEN_WIDTH, marginTop: 20}}>
                                    <ScrollView
                                        style={{flex: 1}}
                                        horizontal
                                        showsHorizontalScrollIndicator={false}
                                    >
                                        <View style={{flex: 1, flexDirection: 'column', height: 170, marginLeft: 40, marginRight: 10}}>
                                            <View style={{flex: 1, flexDirection: 'row'}}>
                                                <CustomButton title="Philosophy" selected={true} />
                                                <CustomButton title="Sport" />
                                                <CustomButton title="Swimming" selected={true} />
                                                <CustomButton title="Religion" />
                                            </View>
                                            <View style={{flex: 1, flexDirection: 'row' }}>
                                                <CustomButton title="Music" />
                                                <CustomButton title="Soccer" selected={true} />
                                                <CustomButton title="Radiohead" selected={true} />
                                                <CustomButton title="Micheal Jackson" />
                                            </View>
                                            <View style={{ flex: 1, flexDirection: 'row' }}>
                                                <CustomButton title="Travelling" selected={true} />
                                                <CustomButton title="Rock'n'Roll" />
                                                <CustomButton title="Dogs" selected={true} />
                                                <CustomButton title="France" selected={true} />
                                            </View>
                                        </View>
                                    </ScrollView>
                                </View>
                            </View>
                            <View style={{flex: 1, marginTop: 30}}>
                                <Text style={{flex: 1, fontSize: 15, color: 'rgba(216, 121, 112, 1)',  marginLeft: 40}}>
                                    INFO
                                </Text>
                                <View style={{flex: 1, flexDirection: 'row', marginTop: 20, marginHorizontal: 30}}>
                                    <View style={{flex: 1, flexDirection: 'row'}}>
                                        <View style={{flex: 1}}>
                                            <Text style={styles.infoTypeLabel}>Age</Text>
                                            <Text style={styles.infoTypeLabel}>Height</Text>
                                            <Text style={styles.infoTypeLabel}>Ethnicity</Text>
                                            <Text style={styles.infoTypeLabel}>Sign</Text>
                                            <Text style={styles.infoTypeLabel}>Religion</Text>
                                        </View>
                                        <View style={{flex: 1, marginLeft: 10}}>
                                            <Text style={styles.infoAnswerLabel}>26</Text>
                                            <Text style={styles.infoAnswerLabel}>5'4"</Text>
                                            <Text style={styles.infoAnswerLabel}>White</Text>
                                            <Text style={styles.infoAnswerLabel}>Pisces</Text>
                                            <Text style={styles.infoAnswerLabel}>Catholic</Text>
                                        </View>
                                    </View>
                                    <View style={{flex: 1, flexDirection: 'row'}}>
                                        <View style={{flex: 1}}>
                                            <Text style={styles.infoTypeLabel}>Body Type</Text>
                                            <Text style={styles.infoTypeLabel}>Diet</Text>
                                            <Text style={styles.infoTypeLabel}>Smoke</Text>
                                            <Text style={styles.infoTypeLabel}>Drink</Text>
                                            <Text style={styles.infoTypeLabel}>Drugs</Text>
                                        </View>
                                        <View style={{flex: 1, marginLeft: 10, marginRight: -20}}>
                                            <Text style={styles.infoAnswerLabel}>Fit</Text>
                                            <Text style={styles.infoAnswerLabel}>Vegan</Text>
                                            <Text style={styles.infoAnswerLabel}>No</Text>
                                            <Text style={styles.infoAnswerLabel}>No</Text>
                                            <Text style={styles.infoAnswerLabel}>Never</Text>
                                        </View>
                                    </View>
                                </View>
                            </View>

                        </ScrollView>
                    </View> :
                    <Text>Loading...</Text>
                }
            </View>
        );
    }
}

const styles = StyleSheet.create({
    statusBar: {
        height: 10,
    },
    navBar: {
        height: 60,
        width: SCREEN_WIDTH,
        justifyContent: 'center',
        alignContent: 'center'
    },
    nameHeader: {
        color: 'white',
        fontSize: 22,
        textAlign: 'center'
    },
    infoTypeLabel: {
        fontSize: 15,
        textAlign: 'right',
        color: 'rgba(126,123,138,1)',

        paddingBottom: 10,
    },
    infoAnswerLabel: {
        fontSize: 15,
        color: 'white',

        paddingBottom: 10,
    }
});

1voto

SmoggeR_js Points 1185

Le problème est que fetch est un async et this n'est parfois pas joignable (ou du moins cela m'est arrivé) donc, pour corriger cela, je crée une variable nommée self avant de créer la classe et je l'égalise pour this comme la façon dont je vais écrire dans le constructeur :

import{..}...; //your imports

let self;

class YourClass() extends Component{
    constructor(){
        //things you do in your constructor and at the end:
        self = this;
    }
}

Ensuite, vous pouvez maintenant utiliser un état comme self.state au lieu de this.state comme self.state.token = responseJson.token; . Le problème que je vois est que si vous voulez mettre un jeton dans state.token, vous ne pouvez pas le faire. self.state.token = responseJson.token; La façon de le faire est self.setState({token:responseJson.token}); ou si vous n'avez pas besoin d'utiliser le self que je vous ai dit, vous pouvez le faire this.setState({token:responseJson.token}); et oublie tout ce que j'ai dit avant J'espère que ça marchera pour vous.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X