Max
Max

Reputation: 1844

Mobx changing observed observable values outside actions is not allowed issue with antd

I want to upload files to server and get response, but if I overriding onChange property of Upload component(from antd) mobx starts giving errors and file uploading is stuck with uploading status(this is actually a common issue, but it is in Chinese and without mobx examples):

Error: [mobx] Since strict-mode is enabled, changing observed observable values outside actions is not allowed. Please wrap the code in an action if this change is intended.
Tried to modify: [email protected][..].percent
...

Tried to modify: [email protected][..].status

Code:

@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>
    )
  }
}

But I'm a little bit confused, because I wrap handleChange method in action.

Upvotes: 1

Views: 7096

Answers (2)

tayfun Kılı&#231;
tayfun Kılı&#231;

Reputation: 2843

Yes try this 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ı.");
                }
           
            });
        });

Upvotes: 0

Ivan V.
Ivan V.

Reputation: 8111

That is a common mistake when working with mobx and asynchronous events.

The action wrapper / decorator only affects the currently running function, not functions that are scheduled (but not invoked) by the current function. The easiest solution is to use runInAction function

try this

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

More information can be found in official documentation: Writing asynchronous actions

Upvotes: 3

Related Questions