mobx@4.x 嚴格模式下 Array.map 的一點問題

背景是 React + mobx@4.x + antd 的項目,而且打開了嚴格模式的狀況下:es6

configure({ enforceActions: true })

大概個人需求是, 將store 中的一個數組(dataSource)在stateless Component中進行渲染,那麼天然就想到了Array 的 map 方法,而後再JSX中直接將數組轉成JSX 代碼塊。數組

const wrapperItem = (title, list) => {
  const result = list.map((item, index) => <Row>
    <Col span={2}>
      {index}
    </Col>
    <Col span={2}>
      {item}
    </Col>
  </Row>)
  return (
    <div>
      <h4>{title}</h4>
      {result}
    </div>
  )
}

上面的demo 代碼中的第二個參數list 會傳入observable 屬性----是一個數組。promise

而後瀏覽器狂報錯誤:瀏覽器

[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: SupernatantStore@13.data.baseInfo

而後看一下 下面的簡單代碼排查錯誤吧:antd

var list = [{'a': 1},{'a': 2}];
var newList = list.map(function(index){
    return index.a += 1;
});
console.log(newList,'newList',list,'list');
// newList 和 list 都改變了。先修改了list的單個key值,再將key值返回,天然就修改了兩個

var list = [{'a': 1},{'a': 2}];
var newList = list.slice(0).map(function(index){
    return index.a += 1;
});
console.log(newList,'newList',list,'list');
// newList 和 list 也都改變了,關鍵很不理解,明明 list 跟 list.slice(0) 已經不是指向同一個數組,爲何list.slice(0) 修改內容還會引起list 也改變?


// wa ... 
// 難受的一批。。。
// slice() concat() 都是淺拷貝,整個數組的指向是不一樣的了,可是,裏面的對象的指向是同一個,因此其實在map裏執行的函數,操做的對象仍是同一個。。。
list.slice(0)[0] === list[0] // truw
list.slice(0) === list // false

一樣的,es6 的解構賦值,也只是淺拷貝:app

var a = {b: {c:111},d:{d:2222}}
    var {b} = a
    b === a.b
    // true

因此說,mobx嚴格模式下一直再警告我不能修改observable 的值。less


constructor() {
    this.initData()
  }
  @action initData = async () => {

     this.baseInfo = await getBaseInfo()
     this.extractInfo = await getExtractInfo()
     this.extractInfo = await getExtractStatus()

  }

我以前的代碼是這樣的,其實,我以爲連@action 也不要,由於就算在嚴格模式下constructor函數中也是能夠修改observable中的值的。異步

那爲何一直報不能在action以外修改observable 屬性的錯誤呢? async

action 僅影響當前運行的函數,而不會影響異步函數,這意味着若是你有setTimeout,promise, then 或 異步的constructor ,在回調更多的狀態改變,這些回調應包裝在 runInAction 中。。。。ide

寫在最後:

  1. 我以前真的沒有好好注意這個問題,對於之前沒有任何限制引用值的 set 的時候,我每每只關心我獲得的值(return 出來的)是否是我想要的。。。。
  2. 說明我對於什麼 slice,concat() 產生一個新的數組這一個概念的理解,只停留於表面。。。。
  3. 我這麼菜,不能總是這樣。
相關文章
相關標籤/搜索