2016-07-30 52 views
0

一切工作正常,直到我運行一個方法來添加一些對象到商店,這是觸發重新呈現在視圖上...東西是在第一頁加載商店組件是包含所有方法的映射,在更新之後以及組件重新呈現時,它會丟失方法並轉換爲普通的js對象,顯然,組件嘗試執行store.get()並且失敗:S不可變的js地圖存儲對象丟失方法

這裏是截圖:

a console log in the store and below a console log to the object on the react component 和一些代碼:

class BlogStore { 
    constructor() { 
    this.bindListeners({ 
     handleBlogs: Actions.UPDATE_BLOGS, 
     handleBlogPost: Actions.UPDATE_BLOG_POST, 
     addMoreBlogs: Actions.ADD_MORE_BLOGS, 
    }); 

    console.log('STORE: state before initialization', this.store); 
    /* here is where the state structure is defined */ 
    this.state = Immutable.Map({ 
     blogs: { 
     blogList: [], 
     meta: { 
      count: 0, 
     }, 
     currentPage: 1, 
     }, 
     blogPost: [] 
    }); 
    } 

    /* here is where the state gets modified */ 
    addMoreBlogs(blogs) { 
    console.log('addMoreBlogs executed'); 
    console.log('STORE: state before convertion to js', this.state); 
    console.log('we have to add this to the store', blogs); 

    //const currentPage = this.state.blogs.currentPage + 1; 

    console.log('STORE: blogList should not be empty', this.state.get('blogs').blogList.concat(blogs.blogList)); 

    const updatedBlogs = this.state.get('blogs').blogList.concat(blogs.blogList); 
    const updatedMeta = this.state.get('blogs').meta; 

    console.log('STORE: updatedBlogs', updatedBlogs); 
    console.log('STORE, updatedMeta', updatedMeta); 

    this.setState(this.state.setIn(
     ['blogs'], 
     { 
     blogList: updatedBlogs, 
     meta: updatedMeta, 
     currentPage: 1, 
     } 
    )); 

     console.log('STORE: updated state', this.state); 
    } 
    ... 

和組件:

class BlogsWrapper extends React.Component { 
    constructor(props) { 
    super(props); 

    /* get the store data and transform it to plain js */ 
    this.state = Store.getState(); 

    //console.log('BLOGSWRAPPER: state gotten in constructor:', this.state); 
    this._onChange = this._onChange.bind(this); 
    } 

    componentDidMount() { 
    Store.listen(this._onChange); 

    // if (this.state.get('blogs').isEmpty()) { 
    // this.context.router.push('/blog/not-found'); 
    // return; 
    // } 
    } 

    componentWillUnmount() { 
    Store.unlisten(this._onChange); 

    //console.log('BLOGSWRAPPER: resetting page counter'); 
    } 

    _onChange() { 
    //this.setState(Store.getState().toJS()); 
    this.setState(Store.getState()); 
    console.log('BLOGSWRAPPER: onchange fired', this.state); 
    }** 

    ... 

對此有何幫助?我無法弄清楚發生了什麼,我也試着在addMoreBlogs方法上創建商店對象,並得到相同的結果。任何幫助/建議將不勝感激。謝謝

回答

1

我最近也有同樣的問題,我想你應該使用mergeIn而不是setIn如果計劃用對象修改狀態。

檢查此jsbin爲相同的解釋。

+0

不錯的做法,改爲mergeIn。謝謝!我認爲它更適合我需要完成的事情。但它不能解決主要問題,組件仍然收到一個對象而不是一個映射 –

+0

我認爲你需要在構造函數中更改爲fromJS而不是immutable.map。這就是我在JSBin示例 – anoop

1

你可以試試這個:

this.setState(this.state.setIn(
    ['blogs'], 
    Immutable.formJS({ 
    blogList: updatedBlogs, 
    meta: updatedMeta, 
    currentPage: 1, 
    }))); 

顯然,這是一個黑客。當你處理不可變狀態時,你應該避免以這種方式更新所有狀態。相反,您需要更新您的不可變對象的確切字段。這就是爲什麼來自Facebook的人建議儘可能保持狀態平坦。

+0

中做的一個選項,但是它很適合用於這種類型的情況。無需使用2個API('fromJS'和'SetIn') – anoop