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

如何在Code Push中实现带进度条的更新加载效果

在React Native Code Push中实现带进度显示的样式化更新流程

问题分析

你当前的代码存在几个关键问题,导致无法实现样式化更新流程:

  • useEffect 未传入依赖数组,会导致组件每次渲染都重复执行同步逻辑
  • 未通过React状态管理更新状态与进度数据,无法将状态变化映射到UI
  • 进度回调的参数类型定义错误(receivedBytes 和 totalBytes 是数字而非字符串)
  • codePush.sync 配置中的 checkFrequency 属于组件包裹时的全局配置,在手动调用sync时无需重复设置

解决方案

以下是修改后的完整代码,实现了加载状态显示和带百分比的进度条功能:

import React, { useEffect, useState } from 'react';
import Navigation from './navigation';
import codePush from 'react-native-code-push';
import { View, Text, ActivityIndicator, ProgressBarIOS, StyleSheet, Platform } from 'react-native';

// 定义更新状态类型
type UpdateStatus = 'idle' | 'checking' | 'downloading' | 'installing' | 'upToDate' | 'installed';

export default function App() {
  // 管理更新状态、进度百分比、是否显示更新UI
  const [updateStatus, setUpdateStatus] = useState<UpdateStatus>('idle');
  const [downloadProgress, setDownloadProgress] = useState<number>(0);
  const [showUpdateUI, setShowUpdateUI] = useState<boolean>(false);

  useEffect(() => {
    const codePushStatusDidChange = (status: any) => {
      switch (status) {
        case codePush.SyncStatus.CHECKING_FOR_UPDATE:
          setUpdateStatus('checking');
          setShowUpdateUI(true);
          console.log('Checking for updates.');
          break;
        case codePush.SyncStatus.DOWNLOADING_PACKAGE:
          setUpdateStatus('downloading');
          console.log('Downloading package.');
          break;
        case codePush.SyncStatus.INSTALLING_UPDATE:
          setUpdateStatus('installing');
          console.log('Installing update.');
          break;
        case codePush.SyncStatus.UP_TO_DATE:
          setUpdateStatus('upToDate');
          setTimeout(() => setShowUpdateUI(false), 1500); // 几秒后隐藏提示
          console.log('Up-to-date.');
          break;
        case codePush.SyncStatus.UPDATE_INSTALLED:
          setUpdateStatus('installed');
          setTimeout(() => setShowUpdateUI(false), 1500);
          console.log('Update installed.');
          break;
      }
    };

    const codePushDownloadDidProgress = (progress: {
      receivedBytes: number;
      totalBytes: number;
    }) => {
      // 计算进度百分比
      const percent = Math.round((progress.receivedBytes / progress.totalBytes) * 100);
      setDownloadProgress(percent);
      console.log(`${percent}% downloaded`);
    };

    const syncImmediate = () => {
      codePush.sync(
        {
          installMode: codePush.InstallMode.IMMEDIATE,
          updateDialog: {
            appendReleaseDescription: true,
            optionalUpdateMessage: 'Updates here..',
            title: 'New Updates',
            optionalInstallButtonLabel: 'Yes',
            optionalIgnoreButtonLabel: 'No',
          },
        },
        codePushStatusDidChange,
        codePushDownloadDidProgress,
      );
    };

    syncImmediate();
  }, []); // 添加空依赖数组,确保只在组件挂载时执行一次

  // 自定义更新UI组件
  const renderUpdateUI = () => {
    if (!showUpdateUI) return null;

    let statusText = '';
    switch (updateStatus) {
      case 'checking':
        statusText = '检查更新中...';
        break;
      case 'downloading':
        statusText = `Updating ${downloadProgress}%`;
        break;
      case 'installing':
        statusText = '安装更新中...';
        break;
      case 'upToDate':
        statusText = '当前已是最新版本';
        break;
      case 'installed':
        statusText = '更新安装完成';
        break;
    }

    return (
      <View style={styles.updateOverlay}>
        <View style={styles.updateContainer}>
          {updateStatus === 'checking' || updateStatus === 'installing' ? (
            <ActivityIndicator size="large" color="#007AFF" style={styles.spinner} />
          ) : (
            updateStatus === 'downloading' &&
            (Platform.OS === 'ios' ? (
              <ProgressBarIOS progress={downloadProgress / 100} style={styles.progressBar} />
            ) : (
              <View style={styles.androidProgressContainer}>
                <View style={[styles.androidProgressBar, { width: `${downloadProgress}%` }]} />
              </View>
            ))
          )}
          <Text style={styles.statusText}>{statusText}</Text>
        </View>
      </View>
    );
  };

  return (
    <>
      {renderUpdateUI()}
      <Navigation />
    </>
  );
}

// 样式定义
const styles = StyleSheet.create({
  updateOverlay: {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
    backgroundColor: 'rgba(0,0,0,0.5)',
    justifyContent: 'center',
    alignItems: 'center',
    zIndex: 9999,
  },
  updateContainer: {
    backgroundColor: 'white',
    padding: 20,
    borderRadius: 10,
    width: '80%',
    alignItems: 'center',
  },
  spinner: {
    marginBottom: 15,
  },
  progressBar: {
    width: '100%',
    marginBottom: 15,
  },
  androidProgressContainer: {
    width: '100%',
    height: 8,
    backgroundColor: '#E0E0E0',
    borderRadius: 4,
    marginBottom: 15,
    overflow: 'hidden',
  },
  androidProgressBar: {
    height: '100%',
    backgroundColor: '#007AFF',
    borderRadius: 4,
  },
  statusText: {
    fontSize: 16,
    color: '#333',
    textAlign: 'center',
  },
});

// 全局配置Code Push,这里设置启动时检查
App = codePush({
  checkFrequency: codePush.CheckFrequency.ON_APP_START
})(App);

关键修改说明

  1. 状态管理:通过useState创建updateStatus、downloadProgress、showUpdateUI三个状态,用于驱动UI变化
  2. UI渲染:添加了全屏遮罩的更新UI,根据不同状态显示加载指示器、进度条和对应文本
  3. 类型修正:修正了进度回调参数的类型定义,确保计算百分比时不会出错
  4. useEffect优化:添加空依赖数组,避免重复执行同步逻辑
  5. 配置调整:将checkFrequency移到组件包裹时的全局配置中,符合Code Push的最佳实践

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 18:10:29