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}/>)}