'FlatList on function React Native
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
Solution 1:[1]
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";
Solution 2:[2]
I would suggest to try and change this:
renderItem={renderItem}
to this:
renderItem={({ item }) => (
<Item
title={item.title}/>)}
Solution 3:[3]
I think I found it, ItemSeparatorComponent is the element that is giving me an error, maybe RN version 0.63 does not support it. It is very strange.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Hen Moshe |
| Solution 3 | jojurdi |
