【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 />}

相关推荐
enjoywindstorm1 小时前
移动端原生框架对比评测
react native
传奇开心果编程12 小时前
【声明式UI开发实用技术学与练】第8课 状态提升与下放
学习·flutter·react native·ui·swiftui·composer
传奇开心果编程1 天前
【现代声明式UI学与练】第4课 列表渲染与 key——如何高效渲染列表、key 的作用、列表重排时的状态保持
学习·flutter·react native·ui·swiftui·android jetpack
传奇开心果编程2 天前
【现代声明式UI学与练】第7课 组件通信——父传子、子传父、跨层级通信、状态提升与 Context
学习·flutter·react native·ui·swiftui·android jetpack
500842 天前
React Native for OpenHarmony 实战:三方库 react-native-url-polyfill 的鸿蒙化适配指南
javascript·react native·react.js·性能优化·electron·harmonyos
传奇开心果编程2 天前
【现代声明式UI学与练】第9课 性能优化——渲染优化、列表优化、内存优化、启动优化
学习·flutter·react native·ui·性能优化·swiftui·android jetpack
500843 天前
React Native for OpenHarmony 实战:三方库 react-native-volume-control 的鸿蒙化适配指南
javascript·react native·react.js·electron·harmonyos
500847 天前
React Native for OpenHarmony 实战:三方库 react-native-crypto-js 的鸿蒙化适配指南
javascript·react native·性能优化·electron·harmonyos
500847 天前
React Native for OpenHarmony 实战:三方库 react-native-device-name 的鸿蒙化适配指南
深度学习·react native·react.js·机器学习·harmonyos
500848 天前
React Native for OpenHarmony 实战:三方库 react-native-torch 的鸿蒙化适配指南
javascript·react native·react.js·harmonyos