Mobx不允许在动作之外更改观察到的可观察值

时间:2019-07-25 18:03:15

标签: reactjs typescript antd mobx

我想将文件上传到服务器并获得响应,但是如果我覆盖onChange组件的Upload属性(来自antdmobx开始给出错误并上传文件处于uploading状态(这实际上是常见的issue,但是它是中文的,没有mobx示例):

  

错误:[mobx]由于启用了严格模式,因此不允许在操作之外更改观察到的可观察值。如果需要进行此更改,请将代码包装在action中。   
  试图修改: UploadComponent@83.fileList [..]。percent   
...
  
  试图修改:UploadComponent@83.fileList [..]。status

代码:

@observer
export class UploadComponent extends Component<{}, {}> {
  @observable fileList: UploadFile[]

  @action
  handleChange = (info: UploadChangeParam) => {
    const fileList = [...info.fileList]
    fileList.map(file => {
      if (file.response) {
        // do somethong with response
      }
      return file
    })
    this.fileList = fileList
  }

  render() {
    return (
      <Upload
        action={"http://localhost:5000/send-file/"}
        accept=".pdf"
        onChange={this.handleChange}
        fileList={this.fileList}
      >
        <Button>
          <Icon type="upload" /> Upload file
        </Button>
      </Upload>
    )
  }
}

但是我有点困惑,因为我将handleChange方法包装在action中。

2 个答案:

答案 0 :(得分:0)

在处理mobx和异步事件时,这是一个常见错误。

动作包装器/装饰器仅影响当前运行的功能,而不影响当前功能调度(但未调用)的功能。 最简单的解决方案是使用runInAction函数

尝试

@action
handleChange = (info: UploadChangeParam) => {
  runInAction(() => {
    const fileList = [...info.fileList]
    fileList.map(file => {
      if (file.response) {
        // do somethong with response
      }
      return file
    })
    this.fileList = fileList
  })
}

更多信息可以在官方文档中找到:Writing asynchronous actions

答案 1 :(得分:0)

是的,试试这个 runInAction

@action addNewtorkListener = async () => {
            this.isNetworkOnline=true;
    
            Network.addListener('networkStatusChange', (status) => {
                debugger
                runInAction("loading activities", () => {
                if (!status.connected) {
                    this.isNetworkOnline=false;
                    toast.error("İnternet Bağlantısı Bulunamadı.");
                    toast.info("Offline Yapılan işlemler offline menüsünden senkronize edilebilir.");
                } else {
                    this.isNetworkOnline=true; 
                    toast.success("İnternet Bağlantısı Sağlandı.");
                }
           
            });
        });