immutable保證store state數據不可直接修改


一、作用

新手使用state時候,容易錯誤的直接更改state數據,在redux中這是不被允許的。Immutable 來解決這個問題。

Immutable Data 就是一旦創建,就不能再被更改的數據。對 Immutable 對象的任何修改或添加刪除操作都會返回一個新的 Immutable 對象。

二、immutable在react中的使用

  • 安裝
  • npm install immutable

    第二步:在reducer.js中,將數據轉成immutable,返回數據也返回一個Immutable對象,

    該對象中有searchFocused數據
  • import * as constants from './constants'
    import {fromJS} from 'immutable'
    // const defaultState = {
    //     searchFocused: false
    // }
    const defaultState = fromJS({
        searchFocused: false
    })
    export default (state=defaultState,action) => {
        if(action.type === constants.SEARCH_FOCUS){
            // return {
            //     searchFocused: true
            // }
            // set是返回了一個全新的對象(這個對象里面的數據是之前對象的數據和現在更改的結合),但是沒有更改原來對象的數據
            return state.set('searchFocused',true)
        }
        if(action.type === constants.SEARCH_BLUR){
            // return {
            //     searchFocused: false
            // }
            return state.set('searchFocused',false)
        }
        return state
    }

    第三步:使用的時候,不能直接state點下面的屬性,因為返回得到是一個Immutable對象,要獲取數據得用get方法

  • const mapStateToProps = (state) => {
        return {
            // searchFocused: state.header.searchFocused
            searchFocused: state.header.get("searchFocused")
        }
    }

     第四步:使用redux-immutable來統一數據格式

   上面代碼中,state還不是一個immutable對象,stata.header又是一個immutable對象,這樣數據格式不統一,容易寫錯,最好是state也是immutable對象

   寫成下面這樣統一數據

state.get("header").get("searchFocused")

如何把state也轉成state對象,就需要在主store的reducer.js中,將combineReducers方法從redux-immutable中導入,而不是從redux中導入,這樣reducer返回的state就是immutable對象了。

 

先npm i redux-immutable

在項目更目錄的store文件夾下的reducer.js中:

// import {combineReducers} from 'redux'
import {combineReducers} from 'redux-immutable'
import {reducer as headerReducer} from '../common/header/store'

const reducer =  combineReducers({
    // 給這個分支
    header: headerReducer
})

export default reducer

 此時組件組獲取數據,就可以寫成如下方式了

const mapStateToProps = (state) => {
    return {
        // searchFocused: state.header.searchFocused
        searchFocused: state.get("header").get("searchFocused")
    }
}

immutable還挺提供了其他api,也可以這么寫:

//searchFocused: state.get("header").get("searchFocused")
searchFocused: state.getIn(["header","searchFocused"])

 

注意點:

當屬性是一個復雜類型時候,fromJS同樣會把其轉成immutable對象

const defaultState = fromJS({
    searchFocused: false,
  // 這也變成immutable對象 searchList: [] })

所以當我們獲取服務器數據,並構造一個action的時候,就把aciton要傳遞的數據改成immutable對象,否則會造成數據格式不統一

const changeList = (data) => ({
    type:constants.CHANGE_LIST,
    data: fromJS(data)
})

export const getList = () => {
    return (dispatch) => {
        axios.get('/api/headerList.json').then(res=>{
            const data = res.data
            dispatch(changeList(data.data))
        }).catch(()=>{
            console.log("error")
        })
    }

immutable對象也提供了map方法,可以按照數組方式去遍歷searchList

{searchList.map(item=>(
      <SearchInfoItem key={item}>{item}</SearchInfoItem>
))}

 immutable對象沒有length屬性,獲取數組長度方法是size

searchList.size === 0 && dispatch(actionCreators.getList())

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM