You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native Expo中BottomSheet渲染数据项时出现TypeError问题求助

解决BottomSheet渲染地标数据时的TypeError问题

嘿,我帮你定位到问题的核心了!你遇到的TypeError: undefined is not an object (evaluating '_ref2.item'),本质是对reanimated-bottom-sheet的API理解有误:

你错误地以为BottomSheet的renderContent(也就是你的renderInner函数)会像React Native Carousel的renderItem一样,自动传入包含当前项的{item}参数,但实际上它并不会。renderContent只是用来渲染底部抽屉的静态结构,不会自动遍历你的coordinates数据——所以你试图访问item.name和item.Description时,item根本就是undefined,自然就抛出了类型错误。

下面是一步步的解决方案:

1. 在状态中添加当前选中索引

首先给组件的state新增一个currentIndex字段,用来跟踪当前选中的地标位置:

state = {
  markers: [],
  currentIndex: 0, // 新增这一行,默认选中第一个地标
  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"), },
  ],
};

2. 更新索引切换函数,同步currentIndex

修改onCarouselItemChange和onMarkerPressed函数,在切换地标时同步更新currentIndex,这样BottomSheet就能拿到最新的选中项:

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();
  // 新增:更新当前选中索引
  this.setState({ currentIndex: index });
};

onMarkerPressed = (location, index) => {
  this._map.animateToRegion({
    latitude: location.latitude,
    longitude: location.longitude,
    latitudeDelta: 0.0045,
    longitudeDelta: 0.0045,
  });
  this._carousel.snapToItem(index);
  // 注意!这里之前写错了:BottomSheet的snapToItem是切换到指定的snap点索引,不是地标索引
  this._bottomsheet.snapToItem(1); // 1对应你设置的400高度,展开抽屉
  // 新增:更新当前选中索引
  this.setState({ currentIndex: index });
};

3. 重写renderInner和renderHeader,从state取数据

去掉这两个函数的{item}参数,直接从state中获取当前选中的地标数据:

renderInner = () => {
  // 从state拿到当前选中的地标
  const currentItem = this.state.coordinates[this.state.currentIndex];
  return (
    <View style={styles.bottomSheetInnerContainer}>
      <Animated.View 
        style={{ 
          zIndex: 1, 
          transform: [{ translateY: this.headerPos }] 
        }} 
      >
        {this.renderHeader(currentItem)}
      </Animated.View>
      <Text style={styles.descriptionText}> {currentItem.Description}</Text>
    </View>
  )
}

renderHeader = (item) => (
  <View style={styles.headerContainer}>
    <Text style={styles.locationHeader}>{item.name}</Text>
    <Image source={require("../assets/upArrow.png")} style={styles.arrowLogo}></Image>
  </View>
);

4. 清理BottomSheet的无效props

BottomSheet不需要data和renderItem这些Carousel专属的配置,把它们删掉:

<BottomSheet
  ref={(c) => { this._bottomsheet = c; }}
  contentPosition={this.trans}
  snapPoints={[100, 400]}
  renderContent={this.renderInner}
  // 移除不需要的data、renderItem、onSnapToItem(如果不需要抽屉高度切换时联动地图的话)
/>

如果希望抽屉切换高度时有额外逻辑,可以保留onSnapToItem,但要注意它的参数是snap点的索引(0对应100高度,1对应400高度),不是地标索引。

这样修改后,当你点击标记或者切换Carousel项时,currentIndex会同步更新,BottomSheet就能正确渲染当前选中地标的名称和描述,再也不会出现undefined的错误啦!

内容的提问来源于stack exchange,提问作者RickPeck

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 16:38:12