React Native - нарушение инварианта, объекты недопустимы в качестве дочернего элемента React - PullRequest
0 голосов
/ 13 апреля 2020

Я делаю приложение на React native с Expo и сталкиваюсь с проблемой при попытке создать сервис аутентификации с помощью ContextProvider, который я сделал

Вот мое приложение. js code

App. js:

import * as React from 'react';
import { AsyncStorage, StatusBar, Platform,  Button, Text, TextInput, View, StyleSheet } from 'react-native';
import { SplashScreen } from 'expo';
import * as Font from 'expo-font';
import { Ionicons } from '@expo/vector-icons';

import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

//SCREENS
import BottomTabNavigator from './navigation/BottomTabNavigator';
import LoginScreen  from './screens/Auth/Login';
import RegisterScreen  from './screens/Auth/Register';
//SCREENS



import AuthContext from "./contexts/AuthContext"

const Stack = createStackNavigator();
import useLinking from './navigation/useLinking';



export default function App(props) {

  const [LOGGED_IN, setLOGGED_IN] = React.useState(false);

  const [isLoadingComplete, setLoadingComplete] = React.useState(false);
  const [initialNavigationState, setInitialNavigationState] = React.useState();
  const containerRef = React.useRef();
  const { getInitialState } = useLinking(containerRef);

  const [state] = React.useReducer({
          isLoading: false
        });

  _retrieveData = async () => {
    try {
      const value = await AsyncStorage.getItem('isLogin');
      if (value) {
        setLOGGED_IN(value)
      }
      console.log('isLogin is false');
    } catch (error) {

    }
  };

  const authContext = React.useMemo(() => ({
      isLogin: async data => {
        setLOGGED_IN(data.LOGGED_IN)
      }
    }),[]
  );



    // Load any resources or data that we need prior to rendering the app
    async function loadResourcesAndDataAsync() {
      try {
        SplashScreen.preventAutoHide();
        setInitialNavigationState(await getInitialState());

        await Font.loadAsync({
          ...Ionicons.font,
          'space-mono': require('./assets/fonts/SpaceMono-Regular.ttf'),
        });
      } catch (e) {
        console.warn(e);
      } finally {
        setLoadingComplete(true);
        SplashScreen.hide();
      }
    }

    loadResourcesAndDataAsync();
    _retrieveData();

  if (!isLoadingComplete && !props.skipLoadingScreen) {
    return null;
  } else {
  return (
    <AuthContext.Provider value={authContext}>
      <NavigationContainer ref={containerRef} initialState={initialNavigationState}>
          { LOGGED_IN ? (
            <Stack.Navigator>
              <Stack.Screen name="Root" component={BottomTabNavigator} /> 
            </Stack.Navigator>
          ) : (
            <Stack.Navigator>
              <Stack.Screen name="Login" options={{headerShown: false}} component={LoginScreen} />
              <Stack.Screen name="Register" options={{headerShown: true}} component={RegisterScreen} />
            </Stack.Navigator>
          )}
      </NavigationContainer>
    </AuthContext.Provider>
  );
}
}

AuthContext. js:

import React from "react";

const AuthContext = React.createContext({
  isLoggedIn: () => {},
  signIn: () => {},
  signOut: () => {}
})

export default AuthContext;

Когда я запускаю приложение на странице входа в Expo-cli, изменяю что-то в коде и сохраняю его, приложение refre sh, и я получил эту ошибку:

Objects are not valid as a React child (found: object with keys {_40, _65, _55, _72}). If you meant to render a collection of children, use an array instead.
    in Login (at SceneView.tsx:98)
    in StaticContainer
    in StaticContainer (at SceneView.tsx:89)
    in EnsureSingleNavigator (at SceneView.tsx:88)
    in SceneView (at useDescriptors.tsx:125)
    in RCTView (at CardContainer.tsx:187)
    in RCTView (at CardContainer.tsx:186)
    in RCTView (at Card.tsx:508)
    in RCTView (at createAnimatedComponent.js:151)
    in AnimatedComponent (at Card.tsx:491)
    in PanGestureHandler (at Card.tsx:484)
    in RCTView (at createAnimatedComponent.js:151)
    in AnimatedComponent (at Card.tsx:480)
    in RCTView (at Card.tsx:473)
    in Card (at CardContainer.tsx:154)
    in CardContainer (at CardStack.tsx:518)
    in RCTView (at CardStack.tsx:109)
    in MaybeScreen (at CardStack.tsx:511)
    in RCTView (at CardStack.tsx:92)
    in MaybeScreenContainer (at CardStack.tsx:410)
    in CardStack (at StackView.tsx:384)
    in KeyboardManager (at StackView.tsx:382)
    in RNCSafeAreaView (at src/index.tsx:26)
    in SafeAreaProvider (at SafeAreaProviderCompat.tsx:42)
    in SafeAreaProviderCompat (at StackView.tsx:379)
    in RCTView (at StackView.tsx:378)
    in StackView (at createStackNavigator.tsx:67)
    in StackNavigator (at App.js:89)
    in EnsureSingleNavigator (at BaseNavigationContainer.tsx:267)
    in ForwardRef(BaseNavigationContainer) (at NavigationContainer.tsx:39)
    in ThemeProvider (at NavigationContainer.tsx:38)
    in ForwardRef(NavigationContainer) (at App.js:83)
    in App (at withExpoRoot.js:26)
    in RootErrorBoundary (at withExpoRoot.js:25)
    in ExpoRoot (at renderApplication.js:40)
    in RCTView (at AppContainer.js:101)
    in RCTView (at AppContainer.js:119)
    in AppContainer (at renderApplication.js:39)
- node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:9033:12 in <anonymous>
- node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:9029:4 in throwOnInvalidObjectType
- node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:10114:31 in reconcileChildFibers
- node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:12446:6 in reconcileChildren
- node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:13587:22 in mountIndeterminateComponent
- node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:307:15 in invokeGuardedCallbackImpl
- node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:531:36 in invokeGuardedCallback
- node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:20488:8 in beginWork$$1
- node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:19370:24 in performUnitOfWork
- node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:19347:39 in workLoopSync
- node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:18997:22 in renderRoot
* [native code]:null in renderRoot
- node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:18709:28 in runRootCallback
* [native code]:null in runRootCallback
- node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:5642:32 in runWithPriority$argument_1
- node_modules\scheduler\cjs\scheduler.development.js:643:23 in unstable_runWithPriority
- node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:5638:22 in flushSyncCallbackQueueImpl
- node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:5627:28 in flushSyncCallbackQueue
- node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:18851:26 in flushSync
- node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:6416:14 in flushSync$argument_0
- node_modules\react-refresh\cjs\react-refresh-runtime.development.js:218:32 in mountedRoots.forEach$argument_0
* [native code]:null in forEach
- node_modules\react-refresh\cjs\react-refresh-runtime.development.js:210:25 in mountedRoots.forEach$argument_0
- node_modules\react-native\Libraries\Core\setUpReactRefresh.js:43:6 in Refresh.performReactRefresh
- node_modules\metro\src\lib\polyfills\require.js:609:10 in setTimeout$argument_0
- node_modules\react-native\Libraries\Core\Timers\JSTimers.js:146:14 in _callTimer
- node_modules\react-native\Libraries\Core\Timers\JSTimers.js:399:17 in callTimers
- node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:436:47 in __callFunction
- node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:111:26 in __guard$argument_0
- node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:384:10 in __guard
- node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:110:17 in __guard$argument_0
* [native code]:null in callFunctionReturnFlushedQueue

Ошибка возникает в (возвратной) части файла (App. js), как показано в журнале ошибок

Редактировать: здесь Логин. js файл:

import React from 'react';
import { View, ScrollView, Image, TouchableOpacity, Text, SafeAreaView, StyleSheet, TouchableWithoutFeedback, KeyboardAvoidingView, Keyboard, Platform, AsyncStorage } from 'react-native';
import { Feather } from '@expo/vector-icons';
import API from '../../components/Api';
import {Button, Input, InputCode, Spinner} from '../../components/AppComponents';
import {setStorage} from '../../components/Functions';
import AuthContext from "../../contexts/AuthContext"

import Colors from '../../constants/Colors';

export default function Login(props) {

  const [username, setUsername] = React.useState('');
  const [password, setPassword] = React.useState('');
  const [isRefresh, setIsRefresh] = React.useState(false);

  const [LOGGED_IN, setLOGGED_IN] = React.useState(false);
  const { isLogin } = React.useContext(AuthContext);
  isLogin({LOGGED_IN});

Init = async () => {
  var Login = await AsyncStorage.getItem('Login');
}


Login = async () => {
  setIsRefresh(true);
  if(username && password){
    API.Login(username, password).then((res) => {
        if(res.isLogin === 'true'){
          setStorage('isLogin', toString(true));
          setStorage('UID', res.user_id );    
          setLOGGED_IN(true);
        }else{
          setStorage('isLogin','');
          setStorage('UID', '');    
          setIsRefresh(false);
          setLOGGED_IN(false);
          alert(res.msg);
        }
    }).catch((error)=>{ 
        setIsRefresh(false);
        alert(error)
    }); 
  }else{
    alert('Complete los datos requeridos')
  }
}

Init();

return (

  <KeyboardAvoidingView behavior={Platform.OS === "ios" ? "padding" : null} style={{ flex: 1 }}>
  <TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
  <SafeAreaView style={styles.container}>
  <View style={{ flex : .1}} />
  <Spinner isLoading={isRefresh}/>


  <View style={{ flex : 1}} >
    <View style={styles.logoContent}>
      <Image source={require('../../assets/images/logo_mini.png')} style={{width:160, height:120}} />
    </View>
  <View style={styles.forms}>
          <Input label="Usuario" round
            onChangeText={setUsername}
            value={username}
            placeholderTextColor="black" icon="user" iconColor="black" textColor="black" borderBottomColor="black"/>


          <Input label="Contraseña" round
            onChangeText={setPassword} 
            value={password}
            placeholderTextColor="black" icon="lock" iconColor="black" textColor="black" borderBottomColor="black" password={true} />

           <View style={{width:'100%', height:'20%'}} />
    </View>
    <View style={{padding:25}} >
        <Button title="INGRESAR"  onPress={()=>Login()} bg={Colors.primary} />
    </View>
  </View>


    </SafeAreaView>
    </TouchableWithoutFeedback>
    <TouchableOpacity style={{alignItems:'center' , padding:20, position:'absolute', bottom:0, left:0, right:0}}  
      onPress={()=>props.navigation.navigate('Register')} >
        <Text>Registrarme</Text>
    </TouchableOpacity>
    </KeyboardAvoidingView>


  );
}


const styles = StyleSheet.create({
  container: {
    flex: 1,
    paddingTop: 20,
    backgroundColor: Colors.primary,
  },
  forms:{    
    flex: .5,
    paddingHorizontal: 25,
  },
  formsCenter:{    
    alignItems:'center',
  },
  logoContent:{
    flex: .3,
    marginBottom: 48,
    alignItems:'center',
    justifyContent: 'center',
  },
  selets:{
    flexDirection:'row',
  },
  contentButton: {
    backgroundColor: '#eee',
    borderRadius:50,
    margin:15,
    height:50,
    width:50,
    textAlign:'center',
    alignItems:'center',
    justifyContent: 'center',
    shadowColor: "#000",
    shadowOffset: {
      width: 0,
      height: 1,
    },
    shadowOpacity: 0.22,
    shadowRadius: 2.22,

    elevation: 3,
  },
  contentButtonText: {
    backgroundColor: '#eee',
    margin:8,
    width:30,
    textAlign:'center',
    alignItems:'center',
    justifyContent: 'center',
    shadowColor: "#000",
    shadowOffset: {
      width: 0,
      height: 1,
    },
    shadowOpacity: 0.22,
    shadowRadius: 2.22,

    elevation: 3,
  },  
  buttonText: {
    textAlign:'center',
    fontSize: 28,
    fontWeight: '700',
    color:'#444'
  },
  buttonTextText: {
    textAlign:'center',
    fontSize: 20,
    fontWeight: '700',
  },  
});
...