绑定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
相关产品推荐
相关产品推荐

