2016-05-31 18 views
11

Tôi đang sử dụng MobX 2.2.2 để cố gắng biến đổi trạng thái bên trong hành động không đồng bộ. Tôi có useStrict của MobX được đặt thành true.Sử dụng trang trí MobX @action với các chức năng không đồng bộ và .then

@action someAsyncFunction(args) { 
    fetch(`http://localhost:8080/some_url`, { 
    method: 'POST', 
    body: { 
     args 
    } 
    }) 
    .then(res => res.json()) 
    .then(json => this.someStateProperty = json) 
    .catch(error => { 
    throw new Error(error) 
    }); 
} 

tôi nhận được:

Error: Error: [mobx] Invariant failed: It is not allowed to create or change state outside an `action` when MobX is in strict mode. Wrap the current method in `action` if this state change is intended 

Tôi có cần phải cung cấp các trang trí @action để báo cáo kết quả .Sau đó thứ hai? Bất kỳ trợ giúp sẽ được đánh giá cao.

Trả lời

17

Tôi có cần cung cấp trang trí @action cho câu lệnh thứ hai không. Bất kỳ trợ giúp sẽ được đánh giá cao.

Điều này khá gần với giải pháp thực tế.

.then(json => this.someStateProperty = json) 

nên

.then(action(json => this.someStateProperty = json)) 

Hãy nhớ action có thể được gọi bằng nhiều cách mà không phải là độc quyền cho @action. Từ the docs on action:

  • action(fn)
  • action(name, fn)
  • @action classMethod
  • @action(name) classMethod
  • @action boundClassMethod = (args) => { body }
  • @action(name) boundClassMethod = (args) => { body }

là một sẽ có các cách hợp lệ để đánh dấu một hàm là một hành động.

Dưới đây là một bin thể hiện giải pháp: http://jsbin.com/peyayiwowu/1/edit?js,output

mobx.useStrict(true); 
const x = mobx.observable(1); 

// Do async stuff 
function asyncStuff() { 
    fetch('http://jsonplaceholder.typicode.com/posts') 
    .then((response) => response.json()) 
    // .then((objects) => x.set(objects[0])) BREAKS 
    .then(mobx.action((objects) => x.set(objects[0]))) 
} 

asyncStuff() 

Còn về lý do lỗi của bạn thực sự xảy ra tôi đoán rằng phía trên mức @action không đệ quy trang trí bất kỳ chức năng như hành động bên trong hàm đó là trang trí, có nghĩa là chức năng ẩn danh của bạn được truyền vào lời hứa của bạn không thực sự là action.

+1

làm thế nào để làm điều này trong async/chờ đợi? – TangMonk

8

Để bổ sung câu trả lời ở trên; thực sự, action chỉ hoạt động trên chức năng bạn truyền cho nó. Các chức năng trong then được chạy trên một ngăn xếp riêng biệt và có thể được nhận dạng dưới dạng các hành động riêng biệt.

Lưu ý rằng bạn cũng có thể cung cấp cho các hành động của một tên cũng vì vậy mà bạn dễ dàng nhận ra chúng trong DevTools nếu bạn sử dụng những:

then(action("update objects after fetch", json => this.someStateProperty = json))

+0

"dưới đây trả lời" * bây giờ: '(lol – m0meni

+0

xuống bỏ phiếu cho tôi! Câu trả lời của bạn là hoàn thành. Sẽ sử dụng ý kiến ​​thời gian tới cho công cụ bổ sung .. – mweststrate

+0

Cố định bằng cách đánh dấu @ AR7 là chính xác :) – twsmith

Các vấn đề liên quan