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

React Native Realm Flexible Sync进度屏实现问题求助

解决Realm Flexible Sync实时进度监听与进度屏实现问题

问题根源分析

  1. 进度模式选择错误:你使用的ProgressMode.ForCurrentlyOutstandingWork仅监听添加监听时已存在的待处理任务,但Flexible Sync中订阅建立后,服务器需要先计算待传输数据量,初始待处理任务为0,只有最终完成时才会触发回调。
  2. 监听时机不对:useEffect依赖为空数组,可能realm.syncSession尚未初始化,导致监听未正确绑定。
  3. 主线程阻塞:大量数据同步操作默认在主线程执行,未完成时渲染主UI会引发卡顿。

解决方案

1. 修正进度监听逻辑

改用ProgressMode.ReportIndefinitely模式,确保持续监听所有后续下载任务;同时在订阅添加完成后再绑定进度监听,保证syncSession已就绪。

2. 实现进度屏控制

通过状态变量跟踪同步进度与完成状态,未完成时仅渲染轻量进度屏,避免主线程阻塞。

修正后的完整代码示例

enum ProgressDirection {
    Download = 'download',
    Upload = 'upload',
}

enum ProgressMode {
    ReportIndefinitely = 'reportIndefinitely',
    ForCurrentlyOutstandingWork = 'forCurrentlyOutstandingWork',
}

const AppSync = () => {
    const app = useApp();
    const realm = useRealm();
    const [syncProgress, setSyncProgress] = useState<number>(0);
    const [isSyncComplete, setIsSyncComplete] = useState<boolean>(false);

    useEffect(() => {
        // 先添加Flexible Sync订阅
        const addSubscription = async () => {
            try {
                await realm.subscriptions.update((mutableSubs) => {
                    // 替换为你的实际数据模型订阅逻辑
                    mutableSubs.add(realm.objects('YourDataModel'));
                });
                // 订阅完成后绑定进度监听
                setupProgressListener();
            } catch (err) {
                console.error('订阅添加失败:', err);
            }
        };

        // 配置进度监听
        const setupProgressListener = () => {
            if (!realm.syncSession) return;

            const progressCallback = (transferred: number, transferable: number) => {
                if (transferable === 0) return; // 避免除以0错误
                const percent = Math.round((transferred / transferable) * 100);
                setSyncProgress(percent);
                
                // 进度完成后停止监听并标记状态
                if (percent >= 100) {
                    setIsSyncComplete(true);
                    realm.syncSession.removeProgressNotification(progressCallback);
                }
            };

            realm.syncSession.addProgressNotification(
                ProgressDirection.Download,
                ProgressMode.ReportIndefinitely,
                progressCallback
            );

            // 组件卸载时清理监听
            return () => {
                realm.syncSession?.removeProgressNotification(progressCallback);
            };
        };

        addSubscription();

        return () => {
            if (!realm.isClosed) realm.close();
        };
    }, [realm]);

    // 同步未完成时显示进度屏
    if (!isSyncComplete) {
        return (
            <div style={{display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100vh'}}>
                <p>数据同步中:{syncProgress}%</p>
                <div style={{width: '80%', height: 10, backgroundColor: '#eee', borderRadius: 5, overflow: 'hidden'}}>
                    <div style={{width: `${syncProgress}%`, height: '100%', backgroundColor: '#4299e1'}}></div>
                </div>
            </div>
        );
    }

    // 同步完成后渲染应用主体内容
    return (
        <div className="app-main-content">
            {/* 你的应用核心UI */}
        </div>
    );
};

额外优化建议

  • 监听连接状态:可以通过realm.syncSession.state判断同步连接状态,处理网络断开等异常场景,给用户重试提示。
  • 使用useSubscription钩子:如果使用Realm React官方的useSubscription,可以更便捷地跟踪订阅状态,结合status字段辅助判断同步进度。
  • 轻量进度屏:进度屏尽量使用简单DOM元素,避免复杂渲染逻辑,减少主线程负担。

内容的提问来源于stack exchange,提问作者Hardik Chavda

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 15:58:11