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

React Native中FlatList展示搜索结果时非可迭代实例展开错误求助

解决FlatList搜索功能中的“非可迭代实例展开”错误

错误原因拆解

  1. 错误的数组展开操作:setResult方法里尝试展开整个API返回对象res(这是包含data、error的对象,并非数组)到数组中,触发“非可迭代实例”报错。同时getData中已对data赋值,又重复调用setResult,造成数据逻辑混乱。
  2. 直接修改React状态:updateSearch里直接给this.state.data赋值,违反React状态不可直接修改的规则,导致状态更新不生效,搜索结果无法正常展示。
  3. 无效的keyExtractor:FlatList的keyExtractor使用了link字段,但API返回的条目里不存在该字段,会引发渲染异常。

修复步骤

  1. 删除冗余的setResult方法,在getData中直接初始化data和temp状态,确保两者都存储API返回的合法公司数组。
  2. 修改updateSearch,通过setState更新过滤后的data,不再直接操作this.state。
  3. 修正keyExtractor,使用每个条目自带的id作为唯一键值。

完整修正代码

import {
  Box,
  Text,
  Image,
  Heading,
  Center,
  ScrollView,
  Spinner,
  FlatList,
  Pressable,
  View,
  Stack,
} from 'native-base';
import React, { Component } from 'react';
import { Dimensions } from 'react-native';
import { ListItem, SearchBar } from '@rneui/themed';

const windowWidth = Dimensions.get('window').width;

class Ilegal extends Component {
  constructor(props) {
    super(props);

    this.state = {
      data: [],
      isLoading: true,
      isFetching: false,
      searchTxt: '',
      error: null,
      temp: [],
    };
  };

  async getData() {
    try {
      const response = await fetch(
        'https://ojk-invest-api.vercel.app/api/illegals'
      );
      const json = await response.json();
      const illegalList = json.data.illegals;
      // 同时初始化data和temp为接口返回的数组
      this.setState({ 
        data: illegalList,
        temp: illegalList
      });
    } catch (error) {
      console.error(error);
      this.setState({ error: error.message });
    } finally {
      this.setState({ 
        isLoading: false,
        isFetching: false, 
      });
    }
  };

  renderHeader = () => {
    return <SearchBar placeholder='Cari Perusahaan..'
      lightTheme round editable={true}
      value={this.state.searchTxt}
      onChangeText={this.updateSearch}
      />
  };

  updateSearch = (searchTxt) => {
    this.setState({ searchTxt }, () => {
      if (!searchTxt.trim()) {
        // 搜索框为空时恢复原始数据
        this.setState({ data: [...this.state.temp] });
        return;
      }
      // 过滤并更新data状态
      const filteredData = this.state.temp.filter(item => 
        item.name.toLowerCase().includes(searchTxt.toLowerCase())
      ).map(({ id, name, type }) => ({ id, name, type }));
      
      this.setState({ data: filteredData });
    });
  };

  componentDidMount() {
    this.getData();
  };

  onRefresh = () => {
    this.setState({ isFetching: true }, () => {
      this.getData();
    });
  };

  renderItem = ({ item }) => {
    const { navigation } = this.props;
    
    return (
      <>
        <Pressable
          style={{ padding: 20, backgroundColor: 'white' }}
          onPress={() => navigation.navigate('Detail Ilegal', { data: item })}>
          <Center>
            <View
              style={{
                flexDirection: 'column',
                justifyContent: 'center',
                alignItems: 'center',
              }}>
              <Text
                style={{
                  fontSize: 16,
                  width: windowWidth - 40,
                  textAlign: 'justify',
                  marginTop: 6,
                }}>
                {item.name}
              </Text>
              <Text
                style={{
                  color: '#808080',
                  fontSize: 14,
                  width: windowWidth - 40,
                  textAlign: 'justify',
                  marginTop: 6,
                }}>
                {item.type}
              </Text>
            </View>
          </Center>
        </Pressable>
        <View style={{ borderWidth: 0.5, borderColor: '#cccccc' }}></View>
      </>
    );
  };

  render() {
    const { data, isLoading, isFetching, error} = this.state;
    return (
      <View style={{ flex:1, justifyContent:'center', backgroundColor:'white', flexDirection: 'column', }}>
          {isLoading ? (
            <Spinner size="large" color="#AA0002" />
          ) : error ? (
            <Text style={{ textAlign: 'center', padding: 20 }}>加载出错:{error}</Text>
          ) : (
            <FlatList
              ListHeaderComponent={this.renderHeader}
              data={data}
              keyExtractor={(item) => item.id.toString()}
              renderItem={this.renderItem}
              onRefresh={this.onRefresh}
              refreshing={isFetching}
            />
          )}
        </View>
    );
  }
}

export default Ilegal;

内容的提问来源于stack exchange,提问作者Ramadhani A.R

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 01:30:22