Home > other >  FlatList on function React Native
FlatList on function React Native

Time:02-16

When I try to load the data dynamically in the FlatList I get the following exception:

Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.

Check the render method of CellRenderer."

{
    "componentStack": "\n    in RCTView (at View.js:34)\n    in View (at VirtualizedList.js:2120)\n    in CellRenderer (at VirtualizedList.js:900)\n    in RCTScrollContentView (at ScrollView.js:1124)\n    in RCTScrollView (at ScrollView.js:1260)\n    in ScrollView (at ScrollView.js:1286)\n    in ScrollView (at VirtualizedList.js:1329)\n    in VirtualizedList (at FlatList.js:624)\n    in FlatList (at homeScreen.js:94)\n    in RCTScrollContentView (at ScrollView.js:1124)\n    in RCTScrollView (at ScrollView.js:1260)\n    in ScrollView (at ScrollView.js:1286)\n    in ScrollView (at homeScreen.js:93)\n    in HomeScreen (at SceneView.tsx:126)\n    in StaticContainer\n    in StaticContainer (at SceneView.tsx:119)\n    in EnsureSingleNavigator (at SceneView.tsx:118)\n    in SceneView (at useDescriptors.tsx:210)\n    in RCTView (at View.js:34)\n    in View (at DebugContainer.native.tsx:27)\n    in DebugContainer (at NativeStackView.native.tsx:75)\n    in MaybeNestedStack (at NativeStackView.native.tsx:246)\n    in RNSScreen (at createAnimatedComponent.js:165)\n    in AnimatedComponent (at createAnimatedComponent.js:215)\n    in ForwardRef(AnimatedComponentWrapper) (at src/index.native.tsx:252)\n    in MaybeFreeze (at src/index.native.tsx:251)\n    in Screen (at NativeStackView.native.tsx:179)\n    in SceneView (at NativeStackView.native.tsx:296)\n    in RNSScreenStack (at src/index.native.tsx:191)\n    in ScreenStack (at NativeStackView.native.tsx:287)\n    in NativeStackViewInner (at NativeStackView.native.tsx:341)\n    in RNCSafeAreaProvider (at SafeAreaContext.tsx:76)\n    in SafeAreaProvider (at SafeAreaProviderCompat.tsx:46)\n    in SafeAreaProviderCompat (at NativeStackView.native.tsx:340)\n    in NativeStackView (at createNativeStackNavigator.tsx:69)\n    in Unknown (at createNativeStackNavigator.tsx:68)\n    in NativeStackNavigator (at stackClient.js:60)\n    in EnsureSingleNavigator (at BaseNavigationContainer.tsx:430)\n    in ForwardRef(BaseNavigationContainer) (at NavigationContainer.tsx:132)\n    in ThemeProvider (at NavigationContainer.tsx:131)\n    in ForwardRef(NavigationContainerInner) (at stackClient.js:59)\n    in StackClient (at App.js:11)\n    in AuthProvider (at App.js:10)\n    in App (at renderApplication.js:45)\n    in RCTView (at View.js:34)\n    in View (at AppContainer.js:106)\n    in RCTView (at View.js:34)\n    in View (at AppContainer.js:132)\n    in AppContainer (at renderApplication.js:39)",
    "isComponentError": true
}
    import React, { useContext, useState, useEffect } from 'react';
    import {
      Button,
      SafeAreaView,
      Image,
      StyleSheet,
      ScrollView,
      View,
      Text,
      TouchableOpacity,
      StatusBar,
      Dimensions,
      Animated,
      Platform,
      ActivityIndicator,
      FlatList,
      Alert,
      TextInput,
      Linking
    } from 'react-native';
    import Footer from './layout/footer';
    
    import axios from 'axios';
    import { AuthContext } from "./components/authprovider";
    
    
    const HomeScreen = ({ navigation }) => {
      const [page, setPage] = useState(1);
      const [items, setItems] = useState([]);
      const [fetchingStatus, setFetchingStatus] = useState(true);
      const [refresh, setRefresh] = useState(false);
    
      const { user, baseUrl, baseUrlApi } = useContext(AuthContext);
    
      const handleLoadMore = () => {
        setPage(page   1);
      };
    
      const onRefresh = () => {
        setItems([]);
        setPage(1);
        setFetchingStatus(true);
      };
    
      const keyExtractor = (item, index) => index.toString();
    
      const Item = ({ title }) => (
        <View style={styles.solutionItemItem}>
          <TouchableOpacity
            style={styles.solutionItemContent}
            activeOpacity={0.7}
            key={index.toString()}
          >
            <View style={styles.viewItem}>
              <Image
                style={{ height: 10, width: 12, marginLeft: 27 }}
                source={require('../assets/images/black-right-icon.png')}
              />
            </View>
            <View style={styles.viewItem2}>
              <Text style={styles.solutionItemName}>
                dd
              </Text>
            </View>
          </TouchableOpacity>
        </View>
      )
    
      const renderItem = ({ item, index }) => (
        <Item title={item.title} />
      );
    
    
      const getData = async (page) => {
        axios.defaults.headers.common['Authorization'] = `Bearer ${user.token.split("|")[1]}`;
        const resp = await axios.get(baseUrlApi   'app/spaces' /*?offset='   page*/);
    
        setFetchingStatus(false); 
        setRefresh(false);
        try {
          setItems([...items, ...resp.data]);
        } catch (error) {
          console.log(error);
          alert(error.message)
        }
      }
    
      useEffect(() => {
        getData(page);
      }, [page]);
    
      return <>
        <ScrollView style={{ backgroundColor: '#fff', height: '100%' }}>
          <FlatList
            style={{ width: '100%', backgroundColor: '#fff' }}
            keyExtractor={keyExtractor}
            ListHeaderComponent={
              <>
                <Text style={{ fontSize: 20, marginTop: 26, marginLeft: 48, marginRight: 48, textTransform: 'uppercase', textAlign: 'center', }}>
                  Mi espacio
                </Text>
                <View style={{ height: 1, backgroundColor: '#DADADA', marginTop: 18, marginBottom: 18, marginLeft: 36, marginRight: 36 }}></View>
                <View style={{
                  marginRight: 17, marginLeft: 17, marginBottom: 13,
                  height: 163,
                  justifyContent: 'center',
                  alignItems: 'center'
                }}>
                  <Image
                    style={{
                      flex: 1, width: '100%', height: null,
                      borderRadius: 6,
                    }}
                    source={{ uri: baseUrl   'images/banner.jpg' }}
                  />
                </View>
                <View style={styles.separator} />
              </>
            }
    
            ListFooterComponent={
              <>
                {fetchingStatus ? <ActivityIndicator size="large" color="#F44336" style={{ marginLeft: 6 }} /> : null}
                <View style={{ height: 180 }}></View>
              </>
            }
    
            numColumns={1}
            ItemSeparatorComponent={<View
              style={{
                height: 7,
                width: "100%",
              }}
            />} 
            refreshing={refresh}
            onEndReachedThreshold={0.1}
            data={items}  
            renderItem={renderItem}  
            ListEmptyComponent={<>
              <Text
                style={styles.emptyListStyle}
                onPress={() => { }}>
                No hay resultados
              </Text>
            </>}
          />
    
        </ScrollView>
    
    
        <Footer navigation={navigation} />
      </>
    
    };
    const styles = StyleSheet.create({
      viewItem: {
        height: '100%',
        width: 59,
        flexDirection: 'row',
        alignItems: 'center'
      },
      viewItem2: {
        marginRight: 59,
        height: '100%',
        paddingRight: 27
      },
      solutionItemItem: {
        width: '100%',
        flex: 1
      },
      solutionItemContent: {
        minHeight: 52,
        alignSelf: 'stretch',
        flex: 1,
        flexDirection: 'row',
        justifyContent: 'flex-start',
        alignContent: 'stretch',
        flexWrap: 'nowrap',
        backgroundColor: '#fff',
        borderRadius: 6,
        borderColor: '#DADADA',
        borderWidth: 1,
        marginLeft: 17,
        marginRight: 17,
        shadowColor: "#000",
        shadowOffset: {
          width: 0,
          height: 0,
        },
        shadowOpacity: 0.1,
        shadowRadius: 3,
        elevation: 5,
      },
      solutionItemName: {
        flexWrap: 'wrap',
        fontSize: 18,
        paddingTop: 12,
        paddingBottom: 12
      },
      emptyListStyle: {
        textAlign: 'center',
        fontSize: 18,
        color: '#000',
        padding: 10,
        marginTop: 30
      },
    });
    
    export default HomeScreen 

CodePudding user response:

I think you have forgotten to add index in 2nd param with title, please add index like

SOLUTION - 1

const Item = ({ title, index }) => (
    <View style={styles.solutionItemItem}>
      <TouchableOpacity
        style={styles.solutionItemContent}
        activeOpacity={0.7}
        key={index.toString()}
      >
        ...
      </TouchableOpacity>
    </View>
)

Send index as prop also like

const renderItem = ({ item, index }) => (
    <Item title={item.title} index={index} />
);

SOLUTION - 2

Try swapping the imports like

import React, { useContext, useState, useEffect } from 'react';
import {
  Button,
  ...
  Linking
} from 'react-native';
import Footer from './layout/footer'; // <----- the error happen
import axios from 'axios';
import { AuthContext } from "./components/authprovider";

After the change:

import Footer from './layout/footer'; // <----- Fixed
import React, { useContext, useState, useEffect } from 'react';
import {
  Button,
  ...
  Linking
} from 'react-native';
import axios from 'axios';
import { AuthContext } from "./components/authprovider";

CodePudding user response:

I would suggest to try and change this:

renderItem={renderItem}

to this:

 renderItem={({ item }) => (
        <Item
          title={item.title}/>)}
          
  • Related