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

绑定ListView触发渲染错误,添加搜索框后问题显现

问题分析与解决方案

我帮你排查了代码和问题场景,这个错误的核心原因是ListView的dataSource初始状态未定义,再加上几个逻辑小问题。你把搜索框移到ListView上方后,组件第一次渲染时this.state.dataSource还没被初始化就传给了ListView,所以抛出了undefined is not an object (evaluating 'this.state.dataSource.rowIdentities')的错误。下面是具体的修复步骤:

1. 初始化state中的dataSource

在组件构造函数里给dataSource设置一个空的初始值,避免第一次渲染时出现undefined:

constructor(props) {
  super(props);
  // 先创建空的数据源实例
  const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
  this.state = {
    text: '',
    dataSource: ds.cloneWithRows([]) // 初始化为空数据源
  };
  this.arrayholder = [];
}

2. 把数据源初始化逻辑移到componentDidMount

不要在renderInitialView里调用setState(这会触发重复渲染),而是在组件挂载完成后初始化数据源:

componentDidMount() {
  const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
  this.setState({
    dataSource: ds.cloneWithRows(this.props.services)
  });
  this.arrayholder = this.props.services;
}

然后修改renderInitialView,去掉里面的setState逻辑,直接使用已初始化的this.state.dataSource:

renderInitialView() {
  if (this.props.detailView === true) {
    return (
      <ServiceDetail />
    );
  } else {
    return (
      <View style={styles.MainContainer}>
        <TextInput
          style={styles.TextInputStyleClass}
          onChangeText={(text) => this.SearchFilterFunction(text)}
          value={this.state.text}
          underlineColorAndroid='transparent'
          placeholder="Search Here"
        />
        <ListView
          enableEmptySections={true}
          dataSource={this.state.dataSource}
          renderSeparator={(sectionId, rowId) => <View key={rowId} style={styles.separator} />}
          renderHeader={this.renderHeader}
          style={{marginTop:10}}
          renderRow={(rowData) => <ServiceItem services={rowData} /> }
        />
      </View>
    );
  }
}

3. 修正搜索过滤的字段访问路径

你的service.json里每个条目直接有ser字段,但代码里写的是item.services.ser,这会导致item.services undefined的错误,改成直接访问item.ser:

SearchFilterFunction(text){
  const newData = this.arrayholder.filter(function(item){
    const itemData = item.ser.toUpperCase(); // 修正字段路径
    const textData = text.toUpperCase();
    return itemData.indexOf(textData) > -1;
  });
  const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
  this.setState({
    dataSource: ds.cloneWithRows(newData),
    text: text
  });
}

4. 补充缺失的TextInput样式

你的样式表中没有定义TextInputStyleClass,需要加上:

const styles = StyleSheet.create({
  // ... 其他原有样式
  TextInputStyleClass: {
    height: 40,
    borderWidth: 1,
    borderColor: '#009688',
    borderRadius: 5,
    paddingLeft: 10,
    marginBottom: 10
  }
});

做完这些修改后,组件就能正常渲染搜索框和ListView,搜索功能也能正常工作了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:10:29