Отрисовано больше крючков, чем во время предыдущего рендеринга

#reactjs #react-native

Вопрос:

Я разрабатывал простое приложение, и я получил вышеприведенное название, которое я хотел бы использовать для службы Firebase, чтобы действовать как система аутентификации приложения

Я разрабатывал фреймворк React всего несколько месяцев, поэтому я предполагаю, что нарушаю некоторые правила React в своем следующем коде:

 import React, {useContext, useEffect, useState} from 'react';
import {
  Text,
  View,
  TextInput,
  Platform,
  KeyboardAvoidingView,
  Keyboard,
  Alert,
  TouchableOpacity,
} from 'react-native';
import auth from '@react-native-firebase/auth';
import {Background} from '../components/Background';
import {WhiteLogo} from '../components/WhiteLogo';
import {loginStyles} from '../theme/loginTheme';
import {useForm} from '../hooks/useForm';
import {StackScreenProps} from '@react-navigation/stack';
import {AuthContext} from '../context/AuthContext';
import {LoginData} from '../interfaces/appInterfaces';

interface Props extends StackScreenProps<any, any> {}

export const LoginScreen = ({navigation}: Props) => {
  const {signIn, errorMessage, removeError} = useContext(AuthContext);

  //Firebase hooks
  // Set an initializing state whilst Firebase connects
  const [initializing, setInitializing] = useState(true);
  const [, setUser] = useState();

  // Handle user state changes
  function onAuthStateChanged(user: LoginData | any) {
    setUser(user);
    if (initializing) setInitializing(false);
  }

  const {email, password, onChange} = useForm({
    email: '',
    password: '',
  });

  /*
    TODO: Crear un Custom hook donde configurar la autenticacion con Firebase
  */

  //Firebase useEffect()
  useEffect(() => {
    const subscriber = auth().onAuthStateChanged(onAuthStateChanged);
    return subscriber; // unsubscribe on unmount
  }, []);

  if (initializing) return null;

  useEffect(() => {
    if (errorMessage.length === 0) return;

    Alert.alert('Login incorrecto', errorMessage, [
      {
        text: 'Ok',
        onPress: removeError,
      },
    ]);
  }, [errorMessage]);

  const onLogin = () => {
    console.log({email, password});
    Keyboard.dismiss();
    signIn({correo: email, password});
  };

  return (
    <>
      {/* Background */}
      <Background />

      <KeyboardAvoidingView
        style={{flex: 1}}
        behavior={Platform.OS === 'ios' ? 'padding' : 'height'}>
        <View style={loginStyles.formContainer}>
          {/* Keyboard avoid view */}
          <WhiteLogo />

          <Text style={loginStyles.title}>Login</Text>

          <Text style={loginStyles.label}>Email:</Text>
          <TextInput
            placeholder="Ingrese su email:"
            placeholderTextColor="rgba(255,255,255,0.4)"
            keyboardType="email-address"
            underlineColorAndroid="white"
            style={[
              loginStyles.inputField,
              Platform.OS === 'ios' amp;amp; loginStyles.inputFieldIOS,
            ]}
            selectionColor="white"
            onChangeText={value => onChange(value, 'email')}
            value={email}
            onSubmitEditing={onLogin}
            autoCapitalize="none"
            autoCorrect={false}
          />

          <Text style={loginStyles.label}>Contraseña:</Text>
          <TextInput
            placeholder="******"
            placeholderTextColor="rgba(255,255,255,0.4)"
            underlineColorAndroid="white"
            secureTextEntry
            style={[
              loginStyles.inputField,
              Platform.OS === 'ios' amp;amp; loginStyles.inputFieldIOS,
            ]}
            selectionColor="white"
            onChangeText={value => onChange(value, 'password')}
            value={password}
            onSubmitEditing={onLogin}
            autoCapitalize="none"
            autoCorrect={false}
          />

          {/* Boton login */}
          <View style={loginStyles.buttonContainer}>
            <TouchableOpacity
              activeOpacity={0.8}
              style={loginStyles.button}
              onPress={onLogin}>
              <Text style={loginStyles.buttonText}>Login</Text>
            </TouchableOpacity>
          </View>

          {/* Crear una nueva cuenta */}
          <View style={loginStyles.newUserContainer}>
            <TouchableOpacity
              activeOpacity={0.8}
              onPress={() => navigation.replace('RegisterScreen')}>
              <Text style={loginStyles.buttonText}>Nueva cuenta </Text>
            </TouchableOpacity>
          </View>
        </View>
      </KeyboardAvoidingView>
    </>
  );
};

 

Я надеюсь, что вы сможете помочь, и если вам это понравится, заранее примите благодарность!

Ответ №1:

useEffect-это крючок, у вас есть оператор возврата перед использованием крючка, поэтому при разных рендерах у вас будет разное количество используемых крючков. Любые заявления о возврате должны быть после всех ваших крючков.

Переместите эту строку

   if (initializing) return null;
 

Чуть выше:

  const onLogin = () => {
    console.log({email, password});
    Keyboard.dismiss();
    signIn({correo: email, password});
  };
 

и дайте ему попробовать.

Комментарии:

1. Спасибо за ваш комментарий !! Суфии, которые вы предлагаете, это работает!