Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I'm trying to dispatch navigation to another screen to get recover password, the issue is that I took an old Code that I had for auth but and has a function using a form reducer which doesn't allow me to navigate giving the error:

ReferenceError: Can't find variable: inputChangeHandler

Here is my Code:

import React, { useState, useReducer, useCallback, useEffect } from 'react';
import { ScrollView, View, KeyboardAvoidingView, StyleSheet, Button, ActivityIndicator, Alert, Image, Text, TouchableNativeFeedback, TouchableOpacity, Platform } from 'react-native';
import { LinearGradient } from 'expo-linear-gradient';
import { useDispatch } from 'react-redux';

import Input from '../components/UI/Input';
import Card from '../components/UI/Card';
import Colors from '../constants/Colors';
import * as authActions from '../store/actions/auth';

const FORM_INPUT_UPDATE = 'FORM_INPUT_UPDATE';

const formReducer = (state, action) => {
    if (action.type === FORM_INPUT_UPDATE) {
        const updatedValues = {
            ...state.inputValues,
            [action.input]: action.value
        };
        const updatedValidities = {
            ...state.inputValidities,
            [action.input]: action.isValid
        };
        let updatedFormIsValid = true;
        for (const key in updatedValidities) {
            updatedFormIsValid = updatedFormIsValid && updatedValidities[key];
        }
        return {
            formIsValid: updatedFormIsValid,
            inputValidities: updatedValidities,
            inputValues: updatedValues
        };
    }
    return state;
};

const AuthScreen = props => {

    let TouchableCmp = TouchableOpacity;

    if (Platform.OS === 'android' && Platform.Version >= 21) {
        TouchableCmp = TouchableNativeFeedback;
    }

    const [isLoading, setIsLoading] = useState(false);
    const [error, setError] = useState();
    const [isSignup, setIsSignup] = useState(false);
    const dispatch = useDispatch();

    const [formState, dispatchFormState] = useReducer(formReducer, {
        inputValues: {
            email: '',
            password: '',
        },
        inputValidities: {
            email: false,
            password:false,
        },
        formIsValid: false,
    });

    useEffect(() => {
        if (error) {
            Alert.alert('Ah Ocurrido un Error', error, [{ text: 'Ok' }]);
        }
    }, [error]);

    const authHandler = async () => {
        let action;

        if (isSignup) {
            action =
                authActions.signup(
                    formState.inputValues.email,
                    formState.inputValues.password,
                )
        } else {
            action =
                authActions.login(
                    formState.inputValues.email,
                    formState.inputValues.password,
                )
        }
        setError(null);
        setIsLoading(true);
        try {
            await dispatch(action);
            //props.navigation.navigate('Shop');
        } catch (err) {
            setError(err.message);
            setIsLoading(false);
        }
    };

    const inputChangeHandler = useCallback(
        (inputIdentifier, inputValue, inputValidity) => {
            dispatchFormState({
                type: FORM_INPUT_UPDATE,
                value: inputValue,
                isValid: inputValidity,
                input: inputIdentifier
            });
        },
        [dispatchFormState]
    );

    const changeRecover = () => {
        props.navigation.navigate('Recover');
    };

    return (
        <KeyboardAvoidingView
            behavior="height"
            keyboardVerticalOffset={50}
            style={styles.screen}>
            <LinearGradient colors={[Colors.background, Colors.primary]} style={styles.gradient}>
                <View style={styles.imageCircle}>
                    <Image
                        resizeMode="cover"
                        style={{ flex: 1 }}
                        source={{ uri: 'https://media.api-sports.io/football/teams/4299.png' }}
                    />
                </View>
                <Card style={styles.authContainer}>
                    <ScrollView>
                        <Input
                            id="email"
                            label="Correo"
                            keyboardType="email-address"
                            required
                            email
                            autoCapitalize="none"
                            errorText="Porfavor introduzca una direccion de Correo Valida"
                            onInputChange={inputChangeHandler}
                            initialValue=''
                        />
                        <Input
                            id="password"
                            label="Contrase?a"
                            keyboardType="default"
                            secureTextEntry
                            required
                            minLength={5}
                            autoCapitalize="none"
                            errorText="Porfavor introduzca una Contrase?a Valida"
                            onInputChange={inputChangeHandler}
                            initialValue=''
                        />
                        <View style={styles.buttonContainer}>
                            {isLoading ? <ActivityIndicator size="small" color={Colors.primary} /> : <Button
                                title={isSignup ? 'Registrarse' : 'Acceder'}
                                color={Colors.primary}
                                onPress={authHandler}
                            />}
                        </View>
                        <View style={styles.buttonContainer}>
                            <Button
                                title={`Cambiar a ${isSignup ? 'Acceder' : 'Registrarse'}`}
                                color={Colors.accent}
                                onPress={() => {
                                    setIsSignup(prevState => !prevState);
                                }}
                            />
                        </View>
                        {isSignup ?
                        null  
                        :<View style={styles.buttonContainer}>
                        <Button
                            title={'Olvide mi Contrase?a'}
                            color={Colors.accent}
                            onPress={changeRecover}
                        />
                    </View>}
                    </ScrollView>
                </Card>
            </LinearGradient>
        </KeyboardAvoidingView>
    );
};

export const screenOptions = {
    headerTitle: 'Ingrese',
}

const styles = StyleSheet.create({
    screen: {
        //flex: 1,
    },
    authContainer: {
        width: '80%',
        maxWidth: 400,
        height: '50%',
        maxHeight: 400,
        padding: 20,
    },
    imageCircle: {
        width: '50%',
        height: '30%',
        // backgroundColor: 'white',
        // borderRadius: 25,
        padding: 8,
        // borderWidth: 2,
        // borderColor: 'rgba(21,21,21,0.2)',
        justifyContent: 'center',
        alignContent: 'center',
        marginBottom: 10,
    },
    buttonContainer: {
        marginTop: 15,
        borderRadius: 50,
    },
    gradient: {
        width: '100%',
        height: '100%',
        justifyContent: 'center',
        alignItems: 'center',
    }
});

export default AuthScreen;

All I want is to be able to change the page if clicked the button (Which by the way I would like to have as a regular hyperlink and don't see it as a button).

But wouldn't like to avoid the functionality which I currently have for Sign In or Register.

Any Ideas?

question from:https://stackoverflow.com/questions/65848650/unable-to-navigate-in-react-native

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
801 views
Welcome To Ask or Share your Answers For Others

1 Answer

For the 12 People who view this post.

I found the answer, at the end I change the variable Action to be a State Variable leaving the Initial State to 'Acceder' which was to log in, on the change button I checked the current state and if it was 'Acceder' I changed into 'Registrarse' which was to Register, and finally when clicked the Forgot Password link I change the State to 'Olvido Contrase?a' then in the auth handler I just evaluated the Action State and dispatch the action accordingly.

Here the Code:

import React, { useState, useReducer, useCallback, useEffect } from 'react';
import { ScrollView, View, KeyboardAvoidingView, StyleSheet, Button, ActivityIndicator, Alert, Image, Text, TouchableNativeFeedback, TouchableOpacity, Platform } from 'react-native';
import { LinearGradient } from 'expo-linear-gradient';
import { useDispatch } from 'react-redux';

import Input from '../components/UI/Input';
import Card from '../components/UI/Card';
import Colors from '../constants/Colors';
import * as authActions from '../store/actions/auth';
import { set } from 'react-native-reanimated';

const FORM_INPUT_UPDATE = 'FORM_INPUT_UPDATE';

const formReducer = (state, action) => {
    if (action.type === FORM_INPUT_UPDATE) {
        const updatedValues = {
            ...state.inputValues,
            [action.input]: action.value
        };
        const updatedValidities = {
            ...state.inputValidities,
            [action.input]: action.isValid
        };
        let updatedFormIsValid = true;
        for (const key in updatedValidities) {
            updatedFormIsValid = updatedFormIsValid && updatedValidities[key];
        }
        return {
            formIsValid: updatedFormIsValid,
            inputValidities: updatedValidities,
            inputValues: updatedValues
        };
    }
    return state;
};

const AuthScreen = props => {

    let TouchableCmp = TouchableOpacity;

    if (Platform.OS === 'android' && Platform.Version >= 21) {
        TouchableCmp = TouchableNativeFeedback;
    }

    const [isLoading, setIsLoading] = useState(false);
    const [error, setError] = useState();
    const [isSignup, setIsSignup] = useState(false);
    const [isAction, setIsAction] = useState('Acceder');
    const dispatch = useDispatch();

    const [formState, dispatchFormState] = useReducer(formReducer, {
        inputValues: {
            email: '',
            password: '',
        },
        inputValidities: {
            email: false,
            password: false,
        },
        formIsValid: false,
    });

    useEffect(() => {
        if (error) {
            Alert.alert('Ah Ocurrido un Error', error, [{ text: 'Ok' }]);
        }
    }, [error]);

    const authHandler = async () => {
        let action;

        if (isAction === 'Registrarse') {
            action =
                authActions.signup(
                    formState.inputValues.email,
                    formState.inputValues.password,
                )
        } else if (isAction === 'Acceder') {
            action =
                authActions.login(
                    formState.inputValues.email,
                    formState.inputValues.password,
                )
        } else {
            action =
                authActions.recoverPassword(
                    formState.inputValues.email
                )
        }
        setError(null);
        setIsLoading(true);
        try {
            await dispatch(action);
            if(isAction === 'Cambiar Contrase?a'){
                setIsLoading(false);
                setIsAction('Acceder');
            }
            //props.navigation.navigate('Shop');
        } catch (err) {
            setError(err.message);
            setIsLoading(false);
        }
    };

    const inputChangeHandler = useCallback(
        (inputIdentifier, inputValue, inputValidity) => {
            dispatchFormState({
                type: FORM_INPUT_UPDATE,
                value: inputValue,
                isValid: inputValidity,
                input: inputIdentifier
            });
        },
        [dispatchFormState]
    );

    return (
        <KeyboardAvoidingView
            behavior="height"
            keyboardVerticalOffset={50}
            style={styles.screen}>
            <LinearGradient colors={[Colors.background, Colors.primary]} style={styles.gradient}>
                <View style={styles.imageCircle}>
                    <Image
                        resizeMode="cover"
                        style={{ flex: 1 }}
                        source={{ uri: 'https://media.api-sports.io/football/teams/4299.png' }}
                    />
                </View>
                <Card style={styles.authContainer}>
                    <ScrollView>
                        <Input
                            id="email"
                            label="Correo"
                            keyboardType="email-address"
                            required
                            email
                            autoCapitalize="none"
                            errorText="Porfavor introduzca una direccion de Correo Valida"
                            onInputChange={inputChangeHandler}
                            initialValue=''
                        />
                        {isAction === 'Cambiar Contrase?a' ?
                            null :
                            <Input
                                id="password"
                                label="Contrase?a"
                                keyboardType="default"
                                secureTextEntry
                                required
                                minLength={5}
                                autoCapitalize="none"
                                errorText="Porfavor introduzca una Contrase?a Valida"
                                onInputChange={inputChangeHandler}
                                initialValue=''
                            />}
                        <View style={styles.buttonContainer}>
                            {isLoading ?
                                <ActivityIndicator size="small" color={Colors.primary} />
                                : <Button
                                    title={isAction}
                                    color={Colors.primary}
                                    onPress={authHandler}
                                />}
                        </View>
                        <View style={styles.buttonContainer}>
                            <Button
                                title={`Cambiar a ${isAction === 'Acceder' ? 'Registrarse' : 'Acceder'}`}
                                color={Colors.accent}
                                onPress={() => {
                                    //setIsSignup(prevState => !prevState);
                                    if (isAction === 'Registrarse') {
                                        setIsAction('Acceder')
                                    } else {
                                        setIsAction('Registrarse')
                                    }
                                }}
                            />
                        </View>
                        {isAction === 'Registrarse' || isAction === 'Cambiar Contrase?a' ?
                            null
                            :
                            <View style={styles.centerView}>
                                <Text style={{ color: 'blue' }}
                                    onPress={() => {
                                        setIsAction('Cambiar Contrase?a');
                                    }}>
                                    Olvide mi Contrase?a
                                 </Text>
                            </View>
                        }
                    </ScrollView>
                </Card>
            </LinearGradient>
        </KeyboardAvoidingView>
    );
};

export const screenOptions = {
    headerTitle: 'Alianza F.C.',
}

const styles = StyleSheet.create({
    screen: {
        //flex: 1,
    },
    authContainer: {
        width: '80%',
        maxWidth: 400,
        height: '50%',
        maxHeight: 400,
        padding: 20,
    },
    imageCircle: {
        width: '50%',
        height: '30%',
        // backgroundColor: 'white',
        // borderRadius: 25,
        padding: 8,
        // borderWidth: 2,
        // borderColor: 'rgba(21,21,21,0.2)',
        justifyContent: 'center',
        alignContent: 'center',
        marginBottom: 10,
    },
    buttonContainer: {
        marginTop: 15,
        borderRadius: 50,
    },
    gradient: {
        width: '100%',
        height: '100%',
        justifyContent: 'center',
        alignItems: 'center',
    },
    centerView: {
        justifyContent: 'center',
        alignItems: 'center',
        marginTop: 10,
    }

});

export default AuthScreen;

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...