Mobx传递回调更新进度时无法实时更新observable的问题
解决Mobx Observable在Firebase Storage回调中未定义的问题
我之前也踩过这个坑,核心问题就是回调函数的上下文(this指向)不对,导致没法访问到你的Mobx observable属性,另外还要注意Mobx对修改可观察对象的规则要求。下面给你具体的解决方案:
问题根源
你在videoUploadTask.on里传入的是普通函数作为回调,这个函数内部的this会指向Firebase的上传任务对象,而不是你的Mobx store实例,所以当你试图更新observable时,自然会出现“未定义”的错误。
具体解决方案
1. 用箭头函数保留上下文
箭头函数会继承外层作用域的this,这样就能正确指向你的Mobx store,直接访问observable:
function putThingInFirebase(thing, cb) { // ... 初始化storageRef等逻辑 const videoUploadTask = videoStorageRef.put(thing) videoUploadTask.on('state_changed', (snap) => { // 改成箭头函数 let progress = (snap.bytesTransferred / snap.totalBytes) * 100; // 现在可以正确访问你的Mobx observable了,比如: this.uploadProgress = progress; // 同时正常调用回调返回进度 if (cb) cb(progress); }); }
2. 显式绑定this到回调函数
如果你偏好使用普通函数,可以通过.bind(this)强制绑定上下文:
function putThingInFirebase(thing, cb) { // ... const videoUploadTask = videoStorageRef.put(thing) videoUploadTask.on('state_changed', function(snap) { let progress = (snap.bytesTransferred / snap.totalBytes) * 100; this.uploadProgress = progress; if (cb) cb(progress); }.bind(this)); // 绑定当前的this到回调函数 }
3. 遵守Mobx的Action更新规则
如果你的Mobx开启了严格模式,直接在回调里修改observable会报错,这时候需要把更新逻辑包裹在action或者runInAction中:
import { observable, action, runInAction } from 'mobx'; class UploadStore { @observable uploadProgress = 0; // 定义action方法来更新进度 @action setUploadProgress(progress) { this.uploadProgress = progress; } putThingInFirebase(thing, cb) { const videoStorageRef = ...; const videoUploadTask = videoStorageRef.put(thing); videoUploadTask.on('state_changed', (snap) => { const progress = (snap.bytesTransferred / snap.totalBytes) * 100; // 调用action方法更新 this.setUploadProgress(progress); // 或者用runInAction包裹直接更新 // runInAction(() => { // this.uploadProgress = progress; // }); if (cb) cb(progress); }); } }
额外提示
如果你是在React组件中使用Mobx,记得用observer装饰器包裹组件,这样observable的变化才能触发组件重新渲染,实时显示上传进度。
内容的提问来源于stack exchange,提问作者rimraf
相关产品推荐
相关产品推荐

