Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
849 views
in Technique[技术] by (71.8m points)

navigation - Unable to Navigate in React Native

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

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

1 Reply

0 votes
by (71.8m points)

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;

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...