如何在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);
关键修改说明
- 状态管理:通过
useState创建updateStatus、downloadProgress、showUpdateUI三个状态,用于驱动UI变化 - UI渲染:添加了全屏遮罩的更新UI,根据不同状态显示加载指示器、进度条和对应文本
- 类型修正:修正了进度回调参数的类型定义,确保计算百分比时不会出错
- useEffect优化:添加空依赖数组,避免重复执行同步逻辑
- 配置调整:将
checkFrequency移到组件包裹时的全局配置中,符合Code Push的最佳实践
内容的提问来源于stack exchange,提问作者greta calamari
相关产品推荐
相关产品推荐

