函数React Native上的FlatList



当我尝试在FlatList中动态加载数据时,我会得到以下异常:

元素类型无效:应为字符串(用于内置组件(或类/函数(用于复合组件(,但实际为:object。

检查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 StaticContainern    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 

我想你忘了用title在第二个参数中添加index,请添加类似的索引

解决方案-1

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

像一样将index作为道具发送

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

解决方案-2

尝试像一样交换进口

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";

更改后:

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";

我建议尝试并更改以下内容:

renderItem={renderItem}

到此:

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

我想我找到了,ItemSeparatorComponent是给我一个错误的元素,也许RN版本0.63不支持它。这很奇怪。