刷新图标一直不消失,有时会消失,但是每次重新启动肯定不消失

来源:21-2 实战仿写小红书App-实现列表显示和分页加载

佚__名

2023-04-30

图片描述
刷新图标一直不消失,有时会消失,但是每次重新启动肯定不消失
Home.tsx代码

import React, {useEffect} from 'react';
import {
  Dimensions,
  FlatList,
  Image,
  StyleSheet,
  Text,
  View,
} from 'react-native';
import {observer, useLocalStore} from 'mobx-react';
import {HomeStore} from './HomeStore';
import icon_heart_empty from '../../assets/icon_heart_empty.png';

const {width: WINDOW_WIDTH} = Dimensions.get('window');

export default observer(() => {
  const store = useLocalStore(() => new HomeStore());

  useEffect(() => {
    (async () => {
      await store.requestHomeList();
    })();
  });

  const onRefresh = async () => {
    store.resetPage();
    await store.requestHomeList();
  };

  const onLoad = async () => {
    await store.requestHomeList();
  };

  const renderItem = ({item, index}: {item: ArticleSimple; index: number}) => {
    return (
      <View style={styles.item}>
        <Image style={styles.itemImage} source={{uri: item.image}} />
        <Text style={styles.titleTxt}>{item.title}</Text>
        <View style={styles.nameLayout}>
          <Image style={styles.avatarImg} source={{uri: item.avatarUrl}} />
          <Text style={styles.nameTxt}>{item.userName}</Text>
          <Image style={styles.heartImg} source={icon_heart_empty} />
          <Text style={styles.countTxt}>{item.favoriteCount}</Text>
        </View>
      </View>
    );
  };

  const Footer = () => {
    return <Text style={styles.footerTxt}>没有更多数据</Text>;
  };

  return (
    <View style={styles.root}>
      <FlatList
        style={styles.flatList}
        data={store.homeList}
        extraData={[store.refreshing]}
        renderItem={renderItem}
        numColumns={2}
        contentContainerStyle={styles.contentContainer}
        refreshing={store.refreshing}
        onRefresh={onRefresh}
        onEndReachedThreshold={0.1}
        ListFooterComponent={Footer}
      />
    </View>
  );
});

const styles = StyleSheet.create({
  root: {
    width: '100%',
    height: '100%',
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#f0f0f0',
  },
  flatList: {
    width: '100%',
    height: '100%',
  },
  item: {
    width: (WINDOW_WIDTH - 18) / 2,
    backgroundColor: 'white',
    marginLeft: 6,
    marginBottom: 6,
    borderRadius: 6,
    overflow: 'hidden',
  },
  contentContainer: {
    paddingTop: 8,
  },
  itemImage: {
    width: '100%',
    height: 250,
    resizeMode: 'cover',
  },
  titleTxt: {
    fontSize: 14,
    color: '#333',
    marginHorizontal: 10,
    marginVertical: 4,
  },
  nameLayout: {
    width: '100%',
    flexDirection: 'row',
    alignItems: 'center',
    paddingHorizontal: 10,
    marginBottom: 10,
  },
  avatarImg: {
    width: 20,
    height: 20,
    resizeMode: 'cover',
    borderRadius: 10,
  },
  nameTxt: {
    fontSize: 12,
    color: '#999',
    marginLeft: 6,
    flex: 1,
  },
  heartImg: {
    width: 20,
    height: 20,
    resizeMode: 'contain',
  },
  countTxt: {
    fontSize: 14,
    color: '#999',
    marginLeft: 4,
  },
  footerTxt: {
    width: '100%',
    fontSize: 14,
    color: '#999',
    marginVertical: 16,
    textAlign: 'center',
    textAlignVertical: 'center',
  },
});

HomeStore.ts代码

import {request} from '../../utils/Request';
import {action, observable} from 'mobx';

const SIZE = 10;

export class HomeStore {
  page: number = 1;
  @observable homeList: ArticleSimple[] = [];
  @observable refreshing: boolean = false;
  @action
  resetPage = () => {
    this.page = 1;
  };
  requestHomeList = async () => {
    if (this.refreshing) {
      return;
    }
    try {
      this.refreshing = true;
      const params = {
        page: this.page,
        size: SIZE,
      };
      const {data} = await request('homeList', params);
      // console.log(`data=${JSON.stringify(data)}`);
      if (data?.length) {
        if (this.page === 1) {
          this.homeList = data;
        } else {
          this.homeList = [...this.homeList, ...data];
        }
        this.page += 1;
      } else {
        if (this.page === 1) {
          this.homeList = [];
        } else {
        }
      }
    } catch (error) {
      console.error(error);
    } finally {
      this.refreshing = false;
    }
  };
}

写回答

1回答

好帮手慕小李

2025-02-20

根据您提供的代码和描述,刷新图标一直不消失的问题可能与FlatList组件的refreshing属性和onRefresh函数的实现有关。以下是一些可能的解决方案:

1. 确保onRefresh函数正确设置refreshing状态

HomeStore中,refreshing状态在请求开始时被设置为true,在请求完成后被设置为false。确保在请求完成后,无论请求成功还是失败,refreshing状态都被正确设置为false

2. 使用useEffect监听refreshing状态变化

Home.tsx中,使用useEffect监听store.refreshing状态的变化,并在状态变化时触发FlatList的重新加载。这样可以确保FlatListrefreshing属性与store.refreshing状态保持同步。


useEffect(() => {
  if (!store.refreshing) {
    // 刷新完成后,可以在这里执行一些操作,例如重置FlatList
  }}, [store.refreshing]);

3. 确保onRefresh函数被正确调用

FlatList组件中,onRefresh属性绑定了onRefresh函数。确保在调用onRefresh函数时,store.refreshing状态被正确设置。


const onRefresh = async () => {
  store.resetPage();
  await store.requestHomeList();};

4. 检查requestHomeList函数的实现

确保requestHomeList函数在请求完成后,无论请求成功还是失败,都将refreshing状态设置为false


requestHomeList = async () => {
  if (this.refreshing) {
    return;
  }
  try {
    this.refreshing = true;
    const params = {
      page: this.page,
      size: SIZE,
    };
    const {data} = await request('homeList', params);
    if (data?.length) {
      if (this.page === 1) {
        this.homeList = data;
      } else {
        this.homeList = [...this.homeList, ...data];
      }
      this.page += 1;
    } else {
      if (this.page === 1) {
        this.homeList = [];
      }
    }
  } catch (error) {
    console.error(error);
  } finally {
    this.refreshing = false; // 确保在finally块中设置refreshing为false
  }};

5. 使用FlatListonMomentumScrollBegin事件

如果问题仍然存在,可以尝试使用FlatListonMomentumScrollBegin事件来监听滚动开始时的状态,并在适当的时候重置refreshing状态。


const onMomentumScrollBegin = () => {
  if (store.refreshing) {
    // 在这里可以执行一些操作,例如重置FlatList
  }};return (
  <View style={styles.root}>
    <FlatList
      style={styles.flatList}
      data={store.homeList}
      extraData={[store.refreshing]}
      renderItem={renderItem}
      numColumns={2}
      contentContainerStyle={styles.contentContainer}
      refreshing={store.refreshing}
      onRefresh={onRefresh}
      onEndReachedThreshold={0.1}
      ListFooterComponent={Footer}
      onMomentumScrollBegin={onMomentumScrollBegin}
    />
  </View>);


0
0

RN从0到1系统精讲与小红书APP实战

30+小案例+2个实战项目,快人一步提升个职业竞争力

295 学习 · 211 问题

查看课程