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

能否在Android模拟器运行时为react-native-sectioned-multi-select添加新数据?

实现搜索栏添加新水果的方案

完全可行,不过得对react-native-sectioned-multi-select的搜索逻辑做些扩展——默认搜索栏只负责过滤现有选项,要实现添加新水果的功能,得结合状态管理和自定义交互来做。下面是具体的实现思路和修改后的代码:

核心思路

  1. 将原本的常量items转为组件状态,这样可以动态更新列表数据
  2. 监听搜索栏的输入内容,判断输入的水果是否已存在于列表中
  3. 如果输入内容不存在,则在搜索结果中添加一个「添加XX」的选项
  4. 当用户选择这个添加选项时,把新水果插入到对应分类的子列表中,并更新状态

修改后的完整代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 19:30:54