目录

一、核心知识点:下拉刷新 标准核心用法

1、核心内置组件

2、下拉刷新 仅需 2 个核心属性(全部属于 RefreshControl)

3、标准实现原理

二、实战一:基础极简版 - ScrollView + RefreshControl 实现下拉刷新

三、实战二:业务完整版 - FlatList + RefreshControl 实现下拉刷新


一、核心知识点:下拉刷新 标准核心用法

1、核心内置组件

所有组件均为 RN 自带,无需安装任何包,是实现下拉刷新的全部核心,缺一不可:

  • ScrollView:基础滚动容器,适合简单页面、短内容页面的下拉刷新(如详情页、图文页)
  • FlatList:高性能列表滚动容器,适合长列表、大数据列表的下拉刷新(商品列表、消息列表、新闻列表),开发中最常用
  • RefreshControl:RN 官方内置的下拉刷新核心控制组件,是实现下拉刷新的唯一载体,所有刷新逻辑 / 状态 / 样式都由它配置,必须配合滚动容器使用

2、下拉刷新 仅需 2 个核心属性(全部属于 RefreshControl

下拉刷新的实现逻辑极简,0 基础只需记住 RefreshControl 的这两个核心属性,这是实现功能的全部关键,无其他复杂配置:

属性名 类型 核心作用
onRefresh () => void 手指下拉页面触发刷新时,执行的回调函数(放「数据请求、数据更新、页面刷新」的业务逻辑)
refreshing boolean 布尔值状态,唯一控制刷新指示器的显示 / 隐藏true 显示加载动画,false 隐藏动画

3、标准实现原理

下拉刷新是 RN 的固定开发范式,所有页面 / 列表的下拉刷新,逻辑完全一致,没有复杂变化,三步即可完成:

  1. 定义一个 refreshing 布尔状态,初始值为 false,用于控制刷新指示器的显隐;
  2. 编写 handleRefresh 回调函数,内部先把 refreshing 设为 true(显示加载),执行数据请求 / 更新逻辑后,再设为 false(隐藏加载);
  3. ScrollView/FlatList 配置 refreshControl 属性,传入 <RefreshControl /> 组件,并把上述状态和函数绑定到组件对应属性上。

二、实战一:基础极简版 - ScrollView + RefreshControl 实现下拉刷新

import React, { useState } from 'react';
import { View, Text, ScrollView, StyleSheet, RefreshControl } from 'react-native';

const PullRefreshBasic = () => {
  const [refreshing, setRefreshing] = useState(false);

  const handleRefresh = () => {
    // 1. 触发刷新 → 立即显示加载动画
    setRefreshing(true);

    // 2. 这里写你的业务逻辑:接口请求/数据更新/重新渲染
    // 模拟真实开发的接口请求延迟(替换成自己的axios/fetch请求即可)
    setTimeout(() => {
      // 3. 逻辑执行完成 → 隐藏加载动画,刷新结束
      setRefreshing(false);
    }, 1500);
  };

  return (
    <ScrollView
      style={styles.container}
      contentContainerStyle={styles.scrollContent}
      refreshControl={
        <RefreshControl
          refreshing={refreshing}
          onRefresh={handleRefresh}
          tintColor="#007DFF"
        />
      }
    >
      <View style={styles.contentBox}>
        <Text style={styles.title}>基础页面下拉刷新</Text>
        <Text style={styles.desc}>手指下拉页面即可触发刷新</Text>
        <Text style={styles.refreshStatus}>{refreshing ? '✅ 正在刷新中...' : '👇 下拉刷新'}</Text>
      </View>
    </ScrollView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#f7f8fa',
  },
  scrollContent: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    padding: 20,
  },
  contentBox: {
    alignItems: 'center',
    gap: 25,
  },
  title: {
    fontSize: 22,
    color: '#333',
    fontWeight: '600',
  },
  desc: {
    fontSize: 16,
    color: '#666',
  },
  refreshStatus: {
    fontSize: 14,
    color: '#007DFF',
    marginTop: 10,
  },
});

export default PullRefreshBasic;


三、实战二:业务完整版 - FlatList + RefreshControl 实现下拉刷新

import React, { useState } from 'react';
import { View, Text, FlatList, StyleSheet, RefreshControl } from 'react-native';

// 1. 定义商品数据类型接口
type GoodsItem = {
  id: string;
  name: string;
  price: string;
};

const PullRefreshBusiness = () => {
  // 2. 列表数据
  const [goodsList, setGoodsList] = useState<GoodsItem[]>([
    { id: '1', name: '鸿蒙智能手机', price: '¥2999' },
    { id: '2', name: '鸿蒙平板电脑', price: '¥1999' },
    { id: '3', name: '鸿蒙智能手表', price: '¥999' },
    { id: '4', name: '鸿蒙无线耳机', price: '¥499' },
  ]);

  // 刷新状态
  const [refreshing, setRefreshing] = useState(false);

  const handleRefresh = () => {
    setRefreshing(true);

    setTimeout(() => {
      // 动态生成唯一id(结合时间戳,避免重复)
      const timestamp = Date.now().toString();
      const newGoodsData: GoodsItem[] = [
        { id: `${timestamp}-1`, name: '鸿蒙智能音箱', price: '¥299' },
        { id: `${timestamp}-2`, name: '鸿蒙平板键盘', price: '¥399' },
        ...goodsList.slice(0, 2), // 保留部分旧数据
      ];

      // 替换整个列表(真实业务逻辑:接口返回最新列表,直接覆盖旧数据)
      setGoodsList(newGoodsData);
      setRefreshing(false);
    }, 1500);
  };

  const renderListItem = ({ item }: { item: GoodsItem }) => (
    <View style={styles.listItem}>
      <Text style={styles.goodsName}>{item.name}</Text>
      <Text style={styles.goodsPrice}>{item.price}</Text>
    </View>
  );

  return (
    <FlatList<GoodsItem>
      style={styles.container}
      data={goodsList}
      renderItem={renderListItem}
      keyExtractor={(item) => item.id} // 现在id是唯一的,无重复
      ItemSeparatorComponent={() => <View style={styles.line} />}
      refreshControl={
        <RefreshControl
          refreshing={refreshing}
          onRefresh={handleRefresh}
          tintColor="#007DFF"
        />
      }
    />
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#f7f8fa',
    paddingHorizontal: 10,
  },
  listItem: {
    backgroundColor: '#fff',
    padding: 18,
    borderRadius: 8,
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
  },
  goodsName: {
    fontSize: 16,
    color: '#333',
  },
  goodsPrice: {
    fontSize: 14,
    color: '#F53F3F',
    fontWeight: '600',
  },
  line: {
    height: 8,
    backgroundColor: '#f7f8fa',
  },
});

export default PullRefreshBusiness;

 


欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐