能否在Android模拟器运行时为react-native-sectioned-multi-select添加新数据?
实现搜索栏添加新水果的方案
完全可行,不过得对react-native-sectioned-multi-select的搜索逻辑做些扩展——默认搜索栏只负责过滤现有选项,要实现添加新水果的功能,得结合状态管理和自定义交互来做。下面是具体的实现思路和修改后的代码:
核心思路
- 将原本的常量
items转为组件状态,这样可以动态更新列表数据 - 监听搜索栏的输入内容,判断输入的水果是否已存在于列表中
- 如果输入内容不存在,则在搜索结果中添加一个「添加XX」的选项
- 当用户选择这个添加选项时,把新水果插入到对应分类的子列表中,并更新状态
修改后的完整代码
import React, { Component } from 'react'; import { View, Alert } from 'react-native'; import Icon from 'react-native-vector-icons/MaterialIcons' import SectionedMultiSelect from 'react-native-sectioned-multi-select'; export default class App extends Component { constructor() { super(); // 将items转为状态,方便动态更新 this.state = { selectedItems: [], items: [ { name: 'Fruits', id: 0, children: [ { name: 'Apple', id: 10 }, { name: 'Strawberry', id: 17 }, { name: 'Pineapple', id: 13 }, { name: 'Banana', id: 14 }, { name: 'Watermelon', id: 15 }, { name: 'Kiwi fruit', id: 16 }, ], }, ], searchText: '', nextId: 18 // 用于生成新水果的唯一id }; } onSelectedItemsChange = (selectedItems) => { const { items, searchText, nextId } = this.state; // 检查选中的是否是添加选项(用特殊id标识,比如-1) const addOptionId = -1; if (selectedItems.includes(addOptionId)) { // 移除添加选项的id,处理添加逻辑 const newSelected = selectedItems.filter(id => id !== addOptionId); // 向Fruits分类添加新水果 const updatedItems = [...items]; updatedItems[0].children.push({ name: searchText.trim(), id: nextId }); // 更新状态:添加新水果,更新选中项,递增id,清空搜索文本 this.setState({ items: updatedItems, selectedItems: [...newSelected, nextId], nextId: nextId + 1, searchText: '' }); Alert.alert('成功', `已添加${searchText.trim()}到水果列表`); } else { this.setState({ selectedItems }); } }; // 监听搜索输入变化 handleSearchChange = (text) => { this.setState({ searchText: text }); }; // 自定义渲染搜索结果项,添加自定义的添加选项 renderItem = ({ item, selected }) => { // 如果是添加选项,单独渲染 if (item.id === -1) { return ( <SectionedMultiSelect.Item item={item} selected={selected} onPress={() => this.onSelectedItemsChange([...this.state.selectedItems, item.id])} /> ); } // 其他项用默认渲染 return <SectionedMultiSelect.Item item={item} selected={selected} />; }; // 处理自定义搜索结果,添加添加选项 getFilteredItems = () => { const { items, searchText } = this.state; if (!searchText.trim()) return items; // 先获取默认的过滤结果 const filtered = SectionedMultiSelect.getFilteredItems(items, searchText, 'id', 'children', 'name'); const searchStr = searchText.trim().toLowerCase(); // 检查搜索的水果是否已存在 const fruitExists = items[0].children.some(fruit => fruit.name.toLowerCase() === searchStr ); // 如果不存在,添加一个自定义的添加选项 if (!fruitExists) { return [ { name: 'Fruits', id: 0, children: [ ...(filtered[0]?.children || []), { name: `添加 "${searchText.trim()}"`, id: -1 } ] } ]; } return filtered; }; render() { const { selectedItems, items, searchText } = this.state; return ( <View style={{ marginTop: 50 }}> <SectionedMultiSelect items={items} // 传入自定义的过滤后的items,包含添加选项 filteredItems={this.getFilteredItems()} IconRenderer={Icon} uniqueKey="id" subKey="children" selectText="选择水果..." showDropDowns={true} readOnlyHeadings={true} onSelectedItemsChange={this.onSelectedItemsChange} selectedItems={selectedItems} // 监听搜索输入变化 onSearchChange={this.handleSearchChange} searchText={searchText} // 自定义渲染列表项 renderItem={this.renderItem} /> </View> ); } }
关键修改点说明
- 状态化items:把原本的常量
items移到组件state中,这样才能动态添加新数据 - 搜索监听与过滤扩展:通过
onSearchChange监听输入,在getFilteredItems中判断输入内容是否已存在,不存在则追加「添加XX」选项 - 添加逻辑处理:在
onSelectedItemsChange中识别添加选项的特殊id,执行添加新水果的操作,并更新列表和选中状态 - 唯一id管理:用
nextId状态来生成新水果的唯一id,避免重复
内容的提问来源于stack exchange,提问作者crag hack
相关产品推荐
相关产品推荐

