一、作用
新手使用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())