TypeError: undefined is not an object (evaluating '_useContext.dispatch') when use context in react native

3.2k views Asked by At

I just follow the steps from a react native course and when I use context to handle sign in, I got this error: enter image description here

I reviewed the code and it equals the instructor's code. The code is below:

src/signIn/index.js

import React, {useState, useContext} from 'react';
import {useNavigation} from '@react-navigation/native';
import AsyncStorage from '@react-native-community/async-storage';
import { UserContext } from '../../contexts/UserContext';
import {
    Container,
    InputArea,
    CustomButton,
    CustomButtonText,
    SignMessageButton,
    SignMessageButtonText,
    SignMessageButtonTextBold,
} from './styles';

import Api from '../../Api';

import SignInput from '../../components/SignInput';

import BarberLogo from '../../assets/barber.svg';
import EmailIcon from '../../assets/email.svg';
import LockIcon from '../../assets/lock.svg';

export default () => {
    const {dispatch: userDispatch} = useContext(UserContext);
    const navigation = useNavigation();

    const [emailField, setEmailField] = useState('');
    const [passwordField, setPasswordField] = useState('');

    const handleSignCLick = async () => {
        if (emailField != '' && passwordField != '') {
            let json = await Api.signIn(emailField, passwordField);

            if (json.token) {
                alert('WORKS!!');
                
                await AsyncStorage.setItem('token', json.token);

                userDispatch({
                    type: 'setAvatar',
                    payload: {
                        avatar: json.data.avatar
                    }
                });

                navigation.reset({
                    routes:[{name:'Maintab'}]

                });

            } else {
                alert('Wrong email or password!');
            }
        } else {
            alert('Fill in the form');
        }
    };

    const handleMessageButtonClick = () => {
        navigation.reset({
            routes: [{name: 'SignUp'}],
        });
    };

    return (
        <Container>
            <BarberLogo width="100%" height="160" />

            <InputArea>
                <SignInput
                    placeholder="Type your email"
                    IconSvg={EmailIcon}
                    value={emailField}
                    onChangeText={(t) => setEmailField(t)}
                />
                <SignInput
                    placeholder="Type your password"
                    IconSvg={LockIcon}
                    value={passwordField}
                    onChangeText={(t) => setPasswordField(t)}
                    password={true}
                />

                <CustomButton onPress={handleSignCLick}>
                    <CustomButtonText>LOGIN</CustomButtonText>
                </CustomButton>
            </InputArea>

            <SignMessageButton onPress={handleMessageButtonClick}>
                <SignMessageButtonText>
                    Does not have an account?
                </SignMessageButtonText>
                <SignMessageButtonTextBold>
                    Sing up
                </SignMessageButtonTextBold>
            </SignMessageButton>
        </Container>
    );
};

When I comment on this lines below the app back to functioning:

if (json.token) {
    alert('WORKS!!');
    
    // await AsyncStorage.setItem('token', json.token);

    // userDispatch({
    //     type: 'setAvatar',
    //     payload: {
    //         avatar: json.data.avatar
    //     }
    // });

    // navigation.reset({
    //     routes:[{name:'Maintab'}]

    // });

} else {
    alert('Wrong email or password!');
}

src/contexts/UserContext.js

import React, {createContext, useReducer} from 'react';
import {initialState, UserReducer} from '../reducers/UserReducer';

export const UserContext = createContext();

export default ({children}) => {
    const [state, dispatch] = useReducer(UserReducer, initialState);

    return (
        <UserContext.Provider valule={{state, dispatch}}>
            {children}
        </UserContext.Provider>
    );
};

I'm new in react native context, so am I missing something?

0

There are 0 answers