【React Native】渐变骨架屏组件SkeletonElement

React Native 渐变骨架屏组件 SkeletonElement 使用指南

一、前言

在移动端开发中,数据加载过程中的空白等待会显著降低用户体验。骨架屏(Skeleton Screen) 是一种广受推崇的加载策略:它通过渲染与真实内容结构一致的灰色占位块,在数据返回前给予用户明确的视觉反馈。

本文提供一个轻量、高性能、支持自定义样式的 SkeletonElement 组件,适用于任何需要占位展示的 UI 元素。


二、组件特性

  • 完全自定义样式 :通过 style 属性控制尺寸、方向、间距等
  • 流畅渐变动画 :使用 Animated 实现原生驱动的高帧率闪烁效果
  • 轻量无依赖:仅基于 React Native 内置模块,零第三方依赖
  • 灵活配色:支持自定义背景色和高亮色
  • 自动清理:组件卸载时自动停止动画,防止内存泄漏

三、快速上手

tsx 复制代码
<View>
  {/* 标题骨架 */}
  <SkeletonElement style={{ height: 24, width: '80%', marginBottom: 16 }} />
  
  {/* 多行文本骨架 */}
  <SkeletonElement style={{ height: 16, width: '100%', marginBottom: 8 }} />
  <SkeletonElement style={{ height: 16, width: '90%', marginBottom: 8 }} />
  <SkeletonElement style={{ height: 16, width: '95%' }} />
  
  {/* 按钮骨架 */}
  <SkeletonElement 
    style={{ 
      height: 48, 
      width: '50%', 
      borderRadius: 24, 
      alignSelf: 'center',
      marginTop: 20 
    }} 
  />
</View>

四、API 说明

Props

属性 类型 默认值 说明
style StyleProp<ViewStyle> undefined 自定义骨架样式(宽高、方向、圆角等)
backgroundColor string #E4E4E4 骨架背景色
highlightColor string #D0D0D0 高亮闪烁色(较背景色稍亮)
speed number 1600 完整闪烁周期(毫秒),值越小动画越快

五、源码解析

核心逻辑

  1. 动画驱动 :使用 useRef(new Animated.Value(0.4)) 创建不触发重渲染的动画值
  2. 循环闪烁 :通过 Animated.loop + Animated.sequence 实现"暗→亮→暗"的循环
  3. 性能优化 :启用 useNativeDriver: true,动画在原生线程运行
  4. 资源清理useEffect 返回清理函数,确保组件卸载时停止动画

关键代码片段

ts 复制代码
const opacityValue = useRef(new Animated.Value(0.4)).current;

useEffect(() => {
  Animated.loop(
    Animated.sequence([
      Animated.timing(opacityValue, { toValue: 1, ... }),
      Animated.timing(opacityValue, { toValue: 0.4, ... })
    ])
  ).start();

  return () => opacityValue.stopAnimation();
}, [opacityValue, speed]);

六、完整源码

tsx 复制代码
import React, {useEffect, useRef} from 'react';
import {Animated, Easing, StyleProp, View, ViewStyle} from 'react-native';

interface SkeletonElementProps {
  style?: StyleProp<ViewStyle>;
  backgroundColor?: string;
  highlightColor?: string;
  speed?: number;
}

export const SkeletonElement: React.FC<SkeletonElementProps> = ({
  style,
  backgroundColor = '#E4E4E4',
  highlightColor = '#D0D0D0',
  speed = 1600,
}) => {
  const useSkeletonAnimation = (speed: number) => {
    const opacityValue = useRef(new Animated.Value(0.4)).current;

    useEffect(() => {
      Animated.loop(
        Animated.sequence([
          Animated.timing(opacityValue, {
            toValue: 1,
            duration: speed / 2,
            easing: Easing.inOut(Easing.ease),
            useNativeDriver: true,
          }),
          Animated.timing(opacityValue, {
            toValue: 0.4,
            duration: speed / 2,
            easing: Easing.inOut(Easing.ease),
            useNativeDriver: true,
          }),
        ]),
      ).start();

      // 返回清理函数
      return () => {
        opacityValue.stopAnimation();
      };
    }, [opacityValue, speed]);

    return opacityValue;
  };

  const opacityValue = useSkeletonAnimation(speed);

  // 合并样式
  const skeletonStyle: ViewStyle = {
    backgroundColor,
    overflow: 'hidden',
    position: 'relative',
    ...(style as ViewStyle),
  };

  // 添加渐变动画效果
  const highlightOverlay = (
    <Animated.View
      style={{
        position: 'absolute',
        top: 0,
        left: 0,
        right: 0,
        bottom: 0,
        backgroundColor: highlightColor,
        opacity: opacityValue,
      }}
    />
  );

  return <View style={skeletonStyle}>{highlightOverlay}</View>;
};

💡 提示:将此组件与条件渲染结合,即可实现优雅的数据加载过渡:

tsx 复制代码
{loading ? <SkeletonElement style={{ height: 200 }} /> : <RealContent />}

相关推荐
花椒技术1 天前
RN 多包热更新实践:更新校验、运行时加载与 Bridge 缓存治理
react native·react.js·harmonyos
互联网推荐官1 天前
上海 APP 开发服务甄选:技术架构设计、全维度判断框架
javascript·react native·react.js·app开发·开发经验·上海
墨狂之逸才5 天前
TRAE IDE 提效实战指南:少加班,多摸鱼
react native
墨狂之逸才5 天前
给 AI Coding Agent 装上 React Native 外挂:callstackincubator/agent-skills 上手指南
react native
墨狂之逸才5 天前
# React Native 人脸识别 UI 方案全对比:嵌入组件 · Activity · Dialog
react native
沙漠6 天前
ReactNative总结系列四 --- FlatList白屏卡顿优化
react native·性能优化
wordbaby8 天前
rn-cross-calendar:一个兼容 React 18/19、RN/RNOH 的跨平台日历组件
前端·react native·harmonyos
沙漠8 天前
ReactNative总结系列三 --- 性能优化
react native·性能优化
leeyi9 天前
Graph 编排:不只是 ReAct 的通用 DAG
react native·agent·graphql
不爱吃糖的程序媛9 天前
React Native 三方库 react-native-version-number 鸿蒙适配实战:从零到版本信息展示
react native·react.js·harmonyos