【问题标题】:React Native - context return undefinedReact Native - 上下文返回未定义
【发布时间】:2020-07-22 21:06:30
【问题描述】:

谁能解释一下为什么上下文返回 undefined..?

用户上下文:

import React, { createContext } from 'react';
import { AsyncStorage } from 'react-native';
import jwtDecode from 'jwt-decode';
export const UserContext = createContext();

export default class UserProvider extends React.Component {
_isMounted = false;

constructor(props) {
    super (props);
    this.state = {
        user: null
    }
}

addUserToken = async (user, token) => {
    if (this._isMounted) {
        try {
            await AsyncStorage.setItem('usertoken', token);
            console.log('Token added successfully:::', token);
            console.log ('User added successfully:', user);
            return true;
        } catch (error) {
            console.log ('Token and user failed');
            return false;
        }
    }
}

getUserToken = async (token) => {
    if (this._isMounted) {
        try {
            const userToken = await AsyncStorage.getItem('usertoken');
            jwtDecode(userToken);
            return token;
        } catch (error) {
            return false;
        }
    }
}

removeUserToken = async (token) => {
    if (this._isMounted) {
        try {
            await AsyncStorage.removeItem('usertoken');
            return true;
        } catch (error) {
            return false;
        }
    }
}

componentDidMount() {
    this._isMounted = true;
    console.log ('componentDidMount in user Context:')
    // get current user
}

componentWillUnmount() {
    this._isMounted = false;
}

render(){
    return (
        <UserContext.Provider value={{
            ...this.state, 
            addUserToken: this.addUserToken, 
            getUserToken: this.getUserToken, 
            removeUserToken: this.removeUserToken
        }}>
        { this.props.children }
        </UserContext.Provider>
    );
}
}

和其他我想使用的屏幕:

import React from 'react';
 import { StyleSheet, Text, View, SafeAreaView, TextInput, TouchableOpacity, ScrollView,       KeyboardAvoidingView, Platform, ActivityIndicator} from 'react-native';
 import Color from '../../colors'
 import {widthPercentageToDP as wp, heightPercentageToDP as hp} from 'react-native-responsive- screen';
 import HideWithKeyboard, { ShowWithKeyboard } from 'react-native-hide-with-keyboard';
  import Snackbar from "react-native-growl";
  import axios from 'axios';
    import API from '../../urls';
  import general from '../../helpers/general';
  import { UserContext } from '../../context/UserContext';

  export default class SignInScreen extends React.Component {

static contextType = UserContext;

_isMounted = false;
constructor(props) {
    super (props);
    this.state = {
        fontLoaded: false,
        visible: false,
        message: '',
        validation: {
            username: {
                status: null,
                value: null
            },
            email: {
                status: null,
                value: null
            }
        },
        loading: false
    }
}

componentDidMount() {
    this._isMounted = true;
    console.log('context in SignInScreen:', this.context) // here is returning undefined
}

componentWillUnmount() {
    this._isMounted = false;
}

_redirectProcesSignInScreen = (username, email) => {
    if (this._isMounted) this.props.navigation.navigate('ProcesSignInScreen', { username: username, email: email });
}

_processSignIn = async () => {
    if (this._isMounted) {
        let _this = this;
        this.setState({loading: true})
        if (this.state.validation.email.status == 'EMPTY' || this.state.validation.email.status == null) {
            this.setState({loading: false})
            this._showSnackBar('Please enter an email to continue', 2000);
            return;
        }

        const username  = this.state.validation.username.value;
        const email  = this.state.validation.email.value;

        try {
            const response = await axios.post(API.BASE_URL + '/users/exist', { username: username, email: email });
            if (response.data.confirmation == 'Success') {
                this.setState({loading: false})
                this._redirectProcesSignInScreen(username, email);
            }
        } catch (error) {
            _this.setState({loading: false})
            general.handleError(error, function(bool, message) {
                _this._showSnackBar(message, 2500);
            })
        }
    }
}
}

_redirectLOGIN = () => {
    if (this._isMounted) this.props.navigation.navigate('LoginScreen');
}

render(){
    return (
        <View style={{flex:1, backgroundColor: Color.BG}}>
        <SafeAreaView style={styles.container}>
                <ScrollView contentContainerStyle={{ flexGrow: 1, justifyContent: 'center' }}>
                    <TouchableOpacity style={styles.contiune_button} onPress={this._processSignIn}>
                        {this.state.loading ? (
                            <ActivityIndicator size="small" color={'#023b2a'} />
                        ) : (
                            <Text style={{alignSelf: "center", fontFamily: Color.FONT_FAMILY_BOLD, color:Color.TEXT_BUTTON, }}>Continue</Text>
                        )}
                    </TouchableOpacity>
                </ScrollView>
        </SafeAreaView >
    </View>
    );
}

}

谁能告诉我为什么返回未定义。

我以前使用过很多次上下文,但这从未发生过。

React 版本:^16.9.0

世博版:~38.0.8

react-dom 版本:~16.11.0

这个项目很重要,谁能解决这个问题就救我……! 谢谢

【问题讨论】:

    标签: reactjs react-native react-native-android undefined react-context


    【解决方案1】:

    您创建了UserProvider,您想通过{ this.props.children } 发送所有其他组件,但我看不到您的主要组件和上下文之间的连接。 您需要使用 &lt;UserProvider&gt; ... &lt;/UserProvider&gt; 来结束 Navigator。

    【讨论】:

    • 谢谢 M.N,你是对的!我忘记在导航器中包装
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-01
    • 1970-01-01
    • 2020-09-26
    • 2021-06-04
    • 1970-01-01
    相关资源
    最近更新 更多