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

React Native数组过滤超500项时应用崩溃问题排查

问题分析与解决方案

1. 修复option.name.toLowerCase() is not a function报错

这个错误的核心是数组里存在部分option对象的name属性不是字符串类型(可能是undefined、null或数字等)。当数组元素超过500时,遍历到这类异常元素就会触发报错。

修改过滤逻辑,添加类型校验:

const filteredOptions = options.filter((option) => {
  // 先确保name是字符串再执行过滤逻辑
  if (typeof option.name !== 'string') return false;
  return option.name.toLowerCase().includes(searchValue.toLowerCase());
});

如果需要保留name为非字符串但有实际值的元素,可以先做类型转换:

const filteredOptions = options.filter((option) => {
  const nameStr = String(option.name || ''); // 把name转为字符串,空值转为空串
  return nameStr.toLowerCase().includes(searchValue.toLowerCase());
});

2. 解决maximum call stack size exceeded栈溢出问题

直接用ScrollView+map渲染1500个元素会一次性创建所有组件,导致JS调用栈溢出,还会严重拖慢性能。换成React Native自带的**FlatList**渲染,它只会渲染当前可见区域的元素,大幅降低内存占用和渲染压力:

<FlatList
  data={filteredOptions}
  keyExtractor={(item) => item.id?.toString() || Math.random().toString()} // 优先用元素唯一ID,避免用index
  renderItem={({ item }) => (
    <View
      style={{
        backgroundColor: "#ddd",
        paddingVertical: 15,
        marginTop: 10,
        paddingHorizontal: 10,
        borderRadius: 8,
      }}
    >
      <TouchableOpacity onPress={() => handleSelection(item)}>
        <Text>{item.name}</Text>
      </TouchableOpacity>
    </View>
  )}
/>

3. 额外性能优化

  • 防抖搜索:避免用户输入时每次字符变化都触发过滤,减少不必要的重渲染:
// 自己实现防抖函数
const debounce = (func, delay) => {
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => func.apply(this, args), delay);
  };
};

const debouncedSetSearchValue = useCallback(debounce((text) => setSearchValue(text), 300), []);

// 修改TextInput的onChangeText
<TextInput
  // ...原有样式和属性
  onChangeText={debouncedSetSearchValue}
/>
  • 预处理数组:提前过滤掉无效元素,避免每次过滤都重复校验:
const [validOptions, setValidOptions] = useState([]);

useEffect(() => {
  // 提前筛选出name为字符串的元素
  const valid = options.filter(opt => typeof opt.name === 'string');
  setValidOptions(valid);
}, [options]);

// 后续过滤直接用预处理后的数组
const filteredOptions = validOptions.filter((option) => {
  return option.name.toLowerCase().includes(searchValue.toLowerCase());
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 23:45:29