当我尝试在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不支持它。这很奇怪。