在 React Native Expo 中将项目渲染到底页时出现类型错误
Posted
技术标签:
【中文标题】在 React Native Expo 中将项目渲染到底页时出现类型错误【英文标题】:Type Error When Rendering Item to Bottomsheet in React Native Expo 【发布时间】:2021-11-21 02:22:38 【问题描述】:我正在开发一个地图应用程序,它使用 JSON 文件来绘制标记并在地标上呈现信息。目前我已经实现了 React Native Carousel 功能,当按下标记时它也会捕捉到地标项目。它还将 Carousel 项捕捉到当前选定的标记。不过我也希望实现一个底部工作表,它可以向上滚动并呈现额外信息:地标名称和描述。
使用与渲染轮播数据相同的方法:名称和图像,尝试在底部屏幕中渲染当前地标时出现错误。
错误信息:
TypeError: undefined is not an object (evalating '_ref2.item')
在我的代码中,renderInner 是一个函数,它应该呈现带有描述的底页,同时还调用 renderHeader 函数——它应该呈现底页的标题以包含地标的标题——“名称”。
这是我当前的代码:
import React, Component from "react";
import StyleSheet,View, Text, Image, Dimensions from "react-native";
import MapView, PROVIDER_GOOGLE, Marker, Callout from "react-native-maps";
import Carousel from "react-native-snap-carousel";
import LinearGradient from "expo-linear-gradient";
import BottomSheet from 'reanimated-bottom-sheet';
import Animated from 'react-native-reanimated';
const block, set, greaterThan, lessThan, Value, cond, sub = Animated
const windowHeight = Dimensions.get("window").height;
export default class ParisMap extends Component
// BottomScreen Constants
trans = new Value(0)
untraversedPos = new Value(0)
prevTrans = new Value(0)
headerPos = block([
cond(
lessThan(this.untraversedPos, sub(this.trans, 100)),
set(this.untraversedPos, sub(this.trans, 100))
),
cond(
greaterThan(this.untraversedPos, this.trans),
set(this.untraversedPos, this.trans)
),
set(this.prevTrans, this.trans),
this.untraversedPos,
])
static navigationOptions =
title: "Map",
;
state =
markers: [],
coordinates: [
name: "Louvre Museum",
latitude: 48.86074344,
longitude: 2.337659481,
Description: "Former historic palace housing huge art collection, from Roman sculptures to da Vinci's 'Mona Lisa.'",
image: require("../assets/louvre.jpeg"),
,
name: "Arc de Triomphe",
latitude: 48.87389506,
longitude: 2.295039178,
Description: "Iconic triumphal arch built to commemorate Napoleon's victories, with an observation deck.",
image: require("../assets/louvre.jpeg"),
,
name: "Eiffel Tower",
latitude: 48.85841765,
longitude: 2.294465185,
Description: "Gustave Eiffel's iconic, wrought-iron 1889 tower, with steps and elevators to observation decks.",
image: require("../assets/louvre.jpeg"),
,
name: "Cathédrale Notre-Dame",
latitude: 48.85294707,
longitude: 2.350142233,
Description: "Towering, 13th-century cathedral with flying buttresses & gargoyles, setting for Hugo's novel.",
image: require("../assets/louvre.jpeg"),
,
name: "Sacré-Cœur",
latitude: 48.88670304,
longitude: 2.343082828,
Description: "Iconic, domed white church, completed in 1914, with interior mosaics, stained-glass windows & crypt.",
image: require("../assets/louvre.jpeg"),
,
],
;
onCarouselItemChange = (index) =>
let location = this.state.coordinates[index];
this._map.animateToRegion(
latitude: location.latitude,
longitude: location.longitude,
latitudeDelta: 0.0045,
longitudeDelta: 0.0045,
);
this.state.markers[index].showCallout();
;
onMarkerPressed = (location, index) =>
this._map.animateToRegion(
latitude: location.latitude,
longitude: location.longitude,
latitudeDelta: 0.0045,
longitudeDelta: 0.0045,
);
this._carousel.snapToItem(index);
this._bottomsheet.snapToItem(index);
;
renderCarouselItem = ( item ) => (
<View style=styles.cardContainer>
<Text style=styles.cardTitle>item.name</Text>
<Image style=styles.cardImage source=item.image />
</View>
);
renderInner = ( item ) => (
<View style=styles.bottomSheetInnerContainer>
<Animated.View
style=
zIndex: 1,
transform: [
translateY: this.headerPos,
,
],
>
this.renderHeader( item )
</Animated.View>
/* <Text style=styles.descriptionText> Here is some sample text</Text> */
<Text style=styles.descriptionText> item.Description</Text>
</View>
)
renderHeader = ( item ) => (
// Header View section - to display name of location
<View style=styles.headerContainer>
/* <Text style=styles.locationHeader>Name of Place</Text> */
<Text style=styles.locationHeader>item.name</Text>
<Image source=require("../assets/upArrow.png") style=styles.arrowLogo></Image>
</View>
);
render()
return (
<View style=styles.container>
<MapView
provider=PROVIDER_GOOGLE
ref=(map) => (this._map = map)
showsUserLocation=true
style=styles.map
initialRegion=
latitude: 48.84574344,
longitude: 2.325659581,
latitudeDelta: 0.155,
longitudeDelta: 0.155,
>
this.state.coordinates.map((marker, index) => (
<Marker
key=marker.name
ref=(ref) => (this.state.markers[index] = ref)
onPress=() => this.onMarkerPressed(marker, index)
coordinate=
latitude: marker.latitude,
longitude: marker.longitude,
>
<Callout>
<Text>marker.name</Text>
</Callout>
</Marker>
))
</MapView>
<View style=styles.bottomView>
<LinearGradient
style=styles.gradient
colors=["rgba(0, 0, 0,0)", "rgba(0, 0, 0,1)"]
/>
</View>
<Carousel
ref=(c) =>
this._carousel = c;
data=this.state.coordinates
containerCustomStyle=styles.carousel
renderItem=this.renderCarouselItem
sliderWidth=Dimensions.get("window").width
itemWidth=300
removeClippedSubviews=false
onSnapToItem=(index) => this.onCarouselItemChange(index)
/>
<BottomSheet
ref=(c) =>
this._bottomsheet = c;
data=this.state.coordinates
renderItem=this.renderHeader
contentPosition=this.trans
snapPoints=[100, 400]
renderContent=this.renderInner
onSnapToItem=(index) => this.onCarouselItemChange(index)
/>
</View>
);
const IMAGE_SIZE = 200
const styles = StyleSheet.create(
container:
...StyleSheet.absoluteFillObject,
,
map:
...StyleSheet.absoluteFillObject,
,
gradient:
...StyleSheet.absoluteFillObject,
height: 5,
bottom: 0,
,
bottomView:
width: "100%",
height: 25,
justifyContent: "center",
alignItems: "center",
position: "absolute",
bottom: 200,
,
carousel:
position: "absolute",
bottom: 0,
marginBottom: 0,
backgroundColor: "#ececec",
height: 220,
,
cardContainer:
backgroundColor: "rgba(0, 0, 0, 0.6)",
height: 200,
width: 300,
padding: 15,
borderRadius: 24,
marginTop: 10,
,
cardImage:
height: 150,
width: 300,
bottom: 0,
position: "absolute",
borderBottomLeftRadius: 24,
borderBottomRightRadius: 24,
,
cardTitle:
color: "white",
fontSize: 20,
alignSelf: "center",
,
cardDescription:
color: "white",
fontSize: 18,
alignSelf: "flex-start",
,
headerContainer:
width: '100%',
backgroundColor: '#ececec',
borderWidth: 0.5,
paddingVertical: 20,
justifyContent: 'center',
flexDirection: 'row',
justifyContent: 'space-between',
,
locationHeader:
fontSize: 18,
position: "relative",
fontWeight: "bold",
marginLeft: 15,
,
arrowLogo:
height: 20,
width: 20,
opacity: 0.5,
marginRight: 15,
,
bottomSheetContainer:
backgroundColor: 'white'
,
bottomSheetInnerContainer:
width: "100%",
color: "white",
backgroundColor: "white",
height: 800
,
descriptionText:
fontSize: 20,
paddingVertical: 30,
marginLeft: 20
);
我相信我的错误出现在 renderInner 和/或 renderHeader 函数中,但是在尝试了许多不同的方法后,我无法让它工作。
当我在renderHeader函数中注释掉这一行时:
<Text style=styles.locationHeader>item.name</Text>
还有 renderInner 函数中的那一行:
<Text style=styles.descriptionText> item.Description</Text>
除了呈现我想要的标题和描述之外,其他一切都很好。我收到此错误是否有原因?
【问题讨论】:
【参考方案1】:底部表格中没有数据!
当您调用 renderItem 时,您必须传递单个坐标!
例如:
renderItem=() => this.renderHeader(this.state.coordinates[0])
【讨论】:
即使我尝试这样做,我也没有收到错误,但它不会呈现任何内容。 'renderContent=() => this.renderInner(this.state.coordinates[0])` 到目前为止,我已经尝试了很多不同的方法,但没有成功以上是关于在 React Native Expo 中将项目渲染到底页时出现类型错误的主要内容,如果未能解决你的问题,请参考以下文章
如何在expo react native App中将api级别29更改为30
未处理的承诺拒绝:TypeError:网络请求失败 - 在 React Native / Expo 中将 Base64(视频/mp4)转换为 Blob
尝试在 create-react-native-app 项目 (expo) 中使用 react-native-fs
react-native-permissions 在 react-native expo 项目中返回 RNPermissions null