React native state.token未定义

时间:2018-03-21 11:08:38

标签: react-native jwt

我创建了一个后端,生成一个记录用户的json web令牌。

enter image description here

但是当我进入下一个屏幕时,令牌未定义。我做错了什么?

设置:

  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;

尝试在下一个屏幕中使用它,然后它是未定义的。

登录屏幕:

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',
  },
});

下一个屏幕

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,
    }
});

1 个答案:

答案 0 :(得分:1)

问题是fetch是一个async函数,而this有时是无法访问的(至少它发生在我身上)所以,为了解决这个问题,我创建了一个名为{{1}的变量在创建类之前,我将其均衡为self,就像我要在构造函数中编写的方式一样:

this

然后,现在您可以使用self.state之类的状态而不是this.state作为import{..}...; //your imports let self; class YourClass() extends Component{ constructor(){ //things you do in your constructor and at the end: self = this; } } 。 我看到的问题是,如果你想把令牌放在state.token中你不能做self.state.token = responseJson.token;,那么这样做的方法是self.state.token = responseJson.token; 或者如果你不需要使用我告诉你可以做的自我 self.setState({token:responseJson.token});忘记我之前说过的一切 我希望它适合你。