在 react 項目裏應用 immutable 對 redux 進行處理,對 List 數據渲染的問題
阿新 • • 發佈:2018-11-29
port 相關 osi color span 行處理 引入 import 代碼
一、reducer文件的處理
先安裝 immutable 與 redux-immutable
yarn add immutable redux-immutable
安裝好後,要在大樹下將子樹合並,在store文件夾的 reducer.js 文件中引入
import { combineReducers } from ‘redux-immutable‘取代原本的
import { combineReducers } from ‘redux‘將子樹合並為一個大樹。 在每一個子樹的 reducer.js 文件中引入 fromJS
import { fromJS } from ‘immutable‘
將子樹的state 轉為 immutable 類型數據
整個是個Map類型,hotCity 是 List 類型
const defaultState = fromJS({ hotCity: [], areas: [], city: ‘全國‘, })
以在城市列表頁,以 redux 維護選擇的城市這個狀態,其所在子樹的 reducer.js 文件如import { fromJS } from ‘immutable
import { fromJS } from ‘immutable‘ import { GET_CITYINFO_DATA, CHANGE_CITY_DATA, } from‘./actionTypes‘ const defaultState = fromJS({ hotCity: [], areas: [], city: ‘全國‘, }) export default (state=defaultState,action) => { if(action.type === GET_CITYINFO_DATA){ // return { // ...state, // hotCity: [...action.result.hotCity], // areas: [...action.result.areas] //} let newList = state.setIn([‘hotCity‘],fromJS(action.result.hotCity)) return newList.setIn([‘areas‘],fromJS(action.result.areas)) //如果要再原來的基礎上修改List數據,就要用 updataIn方法如下 插入兩個 List // let newList = newProjectInfo.updateIn([‘projectInfo‘],list => list.concat(fromJS(action.result.loadMore),fromJS(action.result.loadMore))) } if(action.type === CHANGE_CITY_DATA){ // return { // ...state, // city: action.city // } return state.setIn([‘city‘],action.city) } return state }
其中註釋掉的是不使用 immutable 的代碼。第二個 import 引入的是 定義的 action.type 值,可以做到避免在一個大樹下有相同的 type 值。其命名如下 :
export const GET_CITYINFO_DATA = ‘address/get_cityInfo_data‘
二、在城市列表頁引入 store 內的數據
先引入 connect
import {connect} from ‘react-redux‘
再定義 mapState 與 mapDispatch。
import {CHANGE_CITY_DATA} from ‘pages/address/actionTypes‘ const mapState = (state) => { return { hotCity: state.getIn([‘address‘,‘hotCity‘]), areas: state.getIn([‘address‘,‘areas‘]), } } const mapDispatch = (dispatch) => { return { loadData () { dispatch(loadListAsync(dispatch)) }, changeCity (city) { dispatch({ type: CHANGE_CITY_DATA, city }) } } }
其中 loadData() 方法,請求了數據, changeCity() 方法 改變了所維護的城市狀態
loadData() 的相關代碼如下:
import { GET_CITYINFO_DATA, } from ‘./actionTypes‘ export const loadCityInfoAsync = (result) => { return { type: GET_CITYINFO_DATA, result } } export const loadListAsync = (dispatch) => { return () => { fetch(‘/api/position/city‘) .then(response => response.json()) .then(result => { dispatch(loadCityInfoAsync(result)) }) } }
三、對數據的渲染
對於 List 類型的數據,利用 map() 進行渲染
代碼如下:
import React,{Component} from ‘react‘ import {connect} from ‘react-redux‘ import BScroll from ‘better-scroll‘ import {AddressContainer} from ‘./styledComponents‘ import {loadListAsync} from ‘pages/address/actionCreator‘ import {CHANGE_CITY_DATA} from ‘pages/address/actionTypes‘ const mapState = (state) => { return { hotCity: state.getIn([‘address‘,‘hotCity‘]), areas: state.getIn([‘address‘,‘areas‘]), } } const mapDispatch = (dispatch) => { return { //請求數據 loadData () { dispatch(loadListAsync(dispatch)) }, //改變redux中所保存的城市信息 changeCity (city) { dispatch({ type: CHANGE_CITY_DATA, city }) } } } class AddressContent extends Component { render(){ // 將 this.props 內的內容解構出來 let { hotCity, areas, changeCity, handleClick } = this.props //為在一頁顯示就沒有進一步拆分,看不慣還請見諒 return ( // 綁定 better-scroll 的滾動根元素 <AddressContainer className="address-com-page" ref={el => this.scrollEl = el}> <div> <div> <div className="address-tit">定位城市</div> <div className="address-hot"> <span>定位失敗</span> </div> </div> <div> <div className="address-tit" ref="hot">熱門城市/區域</div> <div className="address-hot"> { // 對 hotCity 進行渲染,先判斷這個數據是否存在,存在再渲染 // 數據是一個 List ,裏面是個 Map , 裏面的 cities 的值 是一個 List 類型,取得後直接進行map() hotCity.get(0) && hotCity.getIn([0,‘cities‘]).map((v,i) => { return ( // 綁定點擊事件,選取所點擊的城市 changeCity() // handleClick() 是路由跳轉,跳回首頁 // cities 的每個子元素都是 Map ,利用 get() 來獲取值 <span key={ v.get(‘cityId‘) } onClick={() => { changeCity(v.get(‘name‘)) handleClick() }} > { v.get(‘name‘) }</span> ) }) } </div> </div> <div> { // 對按字母順序排列的城市列表進行渲染 areas.map((v,i) => { return ( <div key={v.get(‘prefix‘)}> {/* 將小寫字母轉為大寫 */} <div className="address-tit">{ v.get(‘prefix‘).toUpperCase() }</div> <ul className="address-detail"> { // 渲染城市列表,並綁定點擊事件 v.get(‘cities‘).map((v,i) => { return ( <li key={v.get(‘cityId‘)} onClick={() => { changeCity(v.get(‘name‘)) handleClick() }}>{ v.get(‘name‘) }</li> ) }) } </ul> </div> ) }) } </div> </div> </AddressContainer> ) } componentDidMount(){ // 調用 mapDispatch 中的loadData() 方法,獲取數據 this.props.loadData() this.bScroll = new BScroll(this.scrollEl,{ click: true, }) } } export default connect(mapState,mapDispatch)(AddressContent)
至此城市列表頁就渲染出來了。
以上就是利用 immutable 處理 redux 的 過程!
如果有問題,歡迎指出。
在 react 項目裏應用 immutable 對 redux 進行處理,對 List 數據渲染的問題