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

在两个不同组件中更新FlatList的问题求助

问题分析与可行修复方案

我来帮你搞定这个问题!你的代码里有两个核心问题导致FlatList不刷新,咱们一步步调整就能解决:

问题1:每次渲染都重置全局变量

HomeScreen是函数组件,每次渲染(包括从NewTask返回时)都会执行内部所有代码。你现在的写法会把global.obj重新赋值成初始的两个任务,把global.refresh设为false——等于直接覆盖了你在NewTask里添加的新数据和刷新标记,FlatList自然不会更新。

问题2:FlatList的数据源和key缺失

你用data = {obj}但没明确指向全局的global.obj,另外FlatList必须设置keyExtractor来保证渲染的稳定性,否则即使数据变化也可能不刷新。


修复后的HomeScreen代码

import { useEffect, useState } from 'react';
import { View, Button, FlatList, StatusBar } from 'react-native';
import moment from 'moment';
import Task from './Task'; // 确保你的Task组件路径正确

function HomeScreen({ navigation }) {
  // 只在组件第一次挂载时初始化全局变量,避免每次渲染重置
  useEffect(() => {
    // 只有当全局obj不存在时才初始化初始数据
    if (!global.obj) {
      const formatedDate = moment(new Date()).format("YYYY-MM-DD");
      const one = { name:'Dishwasher', task:"Clean", time:formatedDate};
      const two = { name:'Fishwasher', task:'Clean', time:formatedDate };
      global.obj = [one, two];
    }
    // 初始化refresh标记(仅第一次执行)
    if (typeof global.refresh === 'undefined') {
      global.refresh = false;
    }
  }, []); // 空依赖数组 = 仅组件挂载时执行一次

  const [selectedId, setSelectedId] = useState(null);

  return (
    <View>
      <Button 
        title="New Task" 
        accessibilityLabel="Create a new Task" 
        onPress={() => navigation.navigate('NewTask')} 
      />
      <FlatList 
        data={global.obj} // 明确使用全局数组
        extraData={global.refresh} // 绑定全局刷新标记
        keyExtractor={(item, index) => index.toString()} // 必须添加,保证渲染稳定性
        renderItem={({ item }) => (
          <View>
            <Task name={item.name} description={item.task} time={item.time}/>
          </View>
        )}
      />
      <StatusBar style="auto" />
    </View>
  );
}

修复后的NewTask代码

import { View, Picker, TextInput, Button } from 'react-native';
import moment from 'moment';

class NewTask extends Component {
  state = { item: 'Car', name: '' };

  updateItem = (item) => {
    this.setState({ item });
  };

  updateName = (name) => {
    this.setState({ name });
  };

  render() {
    return (
      <View>
        <Picker selectedValue={this.state.item} onValueChange={this.updateItem}>
          <Picker.Item label="Car" value="Car" />
          <Picker.Item label="HVAC Unit" value="HVAC" />
          <Picker.Item label="Fridge" value="Fridge" />
          <Picker.Item label="Smoke Detector" value="Smoke" />
          <Picker.Item label="Dryer" value="Dryer" />
          <Picker.Item label="Water Heater" value="water" />
        </Picker>
        <TextInput 
          placeholder="Name: " 
          label='Name: ' 
          value={this.state.name} 
          onChangeText={this.updateName}
        />
        <Button 
          title="Create Task" 
          onPress={() => {
            // 生成新任务并添加到全局数组
            const formatedDate = moment(new Date()).format("YYYY-MM-DD");
            const newTask = {
              name: this.state.name,
              task: this.state.item, // 这里根据你的需求调整字段对应关系
              time: formatedDate
            };
            global.obj.push(newTask);
            // 切换refresh状态触发FlatList刷新
            global.refresh = !global.refresh;
            // 返回首页
            this.props.navigation.navigate('Home');
          }} 
        />
      </View>
    );
  }
}

为什么这样改能生效?

  1. 用useEffect的空依赖数组,保证全局变量只在HomeScreen第一次加载时初始化,不会覆盖你添加的新任务。
  2. FlatList明确绑定global.obj作为数据源,同时通过extraData={global.refresh}监听状态变化,只要refresh值切换,就会重新渲染列表。
  3. 添加keyExtractor解决FlatList的渲染稳定性问题,避免数据变化但列表不更新的隐性bug。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:13:52