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

React Native可搜索FlatList无法渲染数据问题求助

问题排查:Expo Android环境下FlatList无法渲染数据

我尝试实现一个可通过搜索栏筛选的FlatList,数据来源于JSONPlaceholder,但列表无法渲染,数据不可见。当前在Expo Android环境下仅显示搜索栏,无列表内容。

FlatListDemo组件代码

import React, { Component } from "react";
import { View, Text, FlatList, Button } from "react-native";
import { ListItem, SearchBar } from "react-native-elements";
 
class FlatListDemo extends Component {
 
  constructor(props) {
    super(props); 
  
    this.state = { 
      loading: false,   
      data: [],
      temp: [],
      error: null,
      search: null
    };
  }
  
  componentDidMount() {
    this.getData();
  }
 
   getData = async ()  => {
    const url = `https://jsonplaceholder.typicode.com/users`;
    this.setState({ loading: true });
      
     try {
        const response = await fetch(url);
        const json = await response.json();
        this.setResult(json);
     } catch (e) {
        this.setState({ error: 'Error Loading content', loading: false });
     }
  };
 
  setResult = (res) => {
    this.setState({
      data: [...this.state.data, ...res],
      temp: [...this.state.temp, ...res],
      error: res.error || null,
      loading: false
    });
  }
 
  renderHeader = () => {
      return <SearchBar placeholder="Search Here..."
          lightTheme round editable={true}
          value={this.state.search}
          onChangeText={this.updateSearch} />; 
  }; 
 
  updateSearch = search => {
        this.setState({ search }, () => {
            if ('' == search) {
                this.setState({
                    data: [...this.state.temp]
                });
                return;
            }
             
            this.state.data = this.state.temp.filter(function(item){
                return item.name.includes(search);
              }).map(function({id, name, email}){
                return {id, name, email};
            });
        });
  };
 
  render() {
    return (
      this.state.error != null ?
        <View style={{flexDirection: 'column',justifyContent: 'center', alignItems: 'center' }}>
          <Text>{this.state.error}</Text>
          <Button onPress={
            () => {
              this.getData();
            }
          } title="Reload" />
        </View> : 
        <FlatList
            ListHeaderComponent={this.renderHeader}
            data={this.state.data}
            keyExtractor={item => item.email}
            renderItem={({ item }) => (
            <ListItem
                roundAvatar
                title={`${item.name}`}
                subtitle={item.email}
            />
        )}
      />
    );
  }
}
 
export default FlatListDemo;

Home组件代码

import React, {useState, useEffect} from 'react'
import { Text, View, StyleSheet, StatusBar, SafeAreaView } from "react-native"
import "firebase/auth";
import 'react-native-gesture-handler';
import "firebase/auth";
import 'firebase/compat/auth';
import 'firebase/compat/firestore';
import FlatListDemo from './FlatListDemo';

const Home: () => React$Node = () => {
    return(
        <>
            <StatusBar barStyle="dark-content"/>
            <SafeAreaView style={{flex: 1}}>
            <FlatListDemo/> 
            </SafeAreaView>
        </>
    );
};

export default Home;

核心问题与修复方案

1. 直接修改state导致组件不更新

在updateSearch方法中,直接赋值this.state.data = ...违反React状态更新规则,React无法监测到这种修改,因此FlatList不会重新渲染。必须使用setState更新数据。

2. 初始数据合并冗余

setResult中使用[...this.state.data, ...res]会在重复调用getData时导致数据重复,首次加载直接赋值即可。

3. 布局与组件属性问题

FlatList未设置flex:1,可能无法占满可用空间;ListItem缺少基础样式,可能导致显示异常。

修复后的FlatListDemo代码

import React, { Component } from "react";
import { View, Text, FlatList, Button } from "react-native";
import { ListItem, SearchBar } from "react-native-elements";
 
class FlatListDemo extends Component {
  constructor(props) {
    super(props); 
  
    this.state = { 
      loading: false,   
      data: [],
      temp: [],
      error: null,
      search: "" // 初始化为空字符串避免异常
    };
  }
  
  componentDidMount() {
    this.getData();
  }
 
  getData = async () => {
    const url = `https://jsonplaceholder.typicode.com/users`;
    this.setState({ loading: true });
      
    try {
      const response = await fetch(url);
      const json = await response.json();
      this.setResult(json);
    } catch (e) {
      this.setState({ error: 'Error Loading content', loading: false });
    }
  };
 
  setResult = (res) => {
    // 直接赋值避免数据重复
    this.setState({
      data: res,
      temp: res,
      error: res.error || null,
      loading: false
    });
  }
 
  renderHeader = () => {
    return <SearchBar 
      placeholder="Search Here..."
      lightTheme 
      round 
      editable={true}
      value={this.state.search}
      onChangeText={this.updateSearch} 
    />; 
  }; 
 
  updateSearch = (search) => {
    this.setState({ search }, () => {
      let filteredData;
      if (!search) {
        filteredData = [...this.state.temp];
      } else {
        // 不区分大小写搜索优化
        const lowerSearch = search.toLowerCase();
        filteredData = this.state.temp.filter(item => 
          item.name.toLowerCase().includes(lowerSearch)
        ).map(({id, name, email}) => ({id, name, email}));
      }
      // 使用setState更新数据触发渲染
      this.setState({ data: filteredData });
    });
  };
 
  render() {
    if (this.state.error) {
      return (
        <View style={{flex: 1, flexDirection: 'column',justifyContent: 'center', alignItems: 'center' }}>
          <Text>{this.state.error}</Text>
          <Button onPress={this.getData} title="Reload" />
        </View>
      );
    }
 
    return (
      <FlatList
        style={{flex: 1}} // 占满可用空间
        ListHeaderComponent={this.renderHeader}
        data={this.state.data}
        keyExtractor={item => item.email}
        renderItem={({ item }) => (
          <ListItem
            roundAvatar
            title={item.name}
            subtitle={item.email}
            containerStyle={{borderBottomWidth: 1, borderBottomColor: '#eee'}} // 添加边框提升可读性
          />
        )}
      />
    );
  }
}
 
export default FlatListDemo;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 21:30:53