解决reducer不能直接'修改'state的问题
虽然immutable看起来直接修改,实际上是返回了一个新的immutable对象
1、安装
cnpm install immutable --save
2、引入
import {fromJS,List} from 'immutable' 还有Map和List等类型,fromJS是为对象准备的
3、将对象状态改变成immutable对象
xx=fromJS({
键值对
})
对象内的数组/对象也会同时被转换成immutable对象,记得使用时区分
3.5数据格式转换
在使用immutable来管理状态后,所有的数据格式都应该是immutable对象
!!!往immutable对象内存储数组等数据的时候,要先fromJS(x)转换成immutable对象
fromJS(x); 能将数据及其内层全转换成immutable对象,能用其他类型转换的,都能使用fromJS
List(x); 转换成immutable数组类型对象,只能转换最外层,内层数据不能转换
4、修改immutable状态
方式一:
xx.set('键名',值)
支持链式调用:xx.set('键名',值).set('键名',值)...
方式二:
xx.merge({
键值对
})
5、设置reducer返回state
6、组件中获取状态
获取到immutable对象后,调用.get('键名')获取,.getIn(['x','xx']); 能获取x内的xx
支持链式调用,链式调用和getIn效果相同
如:this.props.state.get('xx')
代码示例:
reducer.js
import {SEARCH_FOCUS,SEARCH_BLUR,CHANGE_LIST,MOUSE_ENTER,MOUSE_LEAVE,CHANGE_PAGE} from './action-type'
import {fromJS} from 'immutable'
const initState=fromJS({
focused:false,
mouseIn:false,
list:[],
page:1,
totalPage:1
})
export default (state=initState,action)=>{
switch(action.type)
{
case SEARCH_FOCUS:
return state.set('focused',true);
case SEARCH_BLUR:
return state.set('focused',false);
case CHANGE_LIST:
return state.merge({
'list':action.data,
'totalPage':action.totalPage
})
case MOUSE_ENTER:
return state.set('mouseIn',true);
case MOUSE_LEAVE:
return state.set('mouseIn',false);
case CHANGE_PAGE:
if(state.get('page')<state.get('totalPage'))
{
return state.set('page',state.get('page')+1);
}else{
return state.set('page',1);
}
default:
return state
}
}
组件使用:
import React,{Component} from 'react'
import { CSSTransition } from 'react-transition-group';
import {connect} from 'react-redux'
import * as action from '../../store/actions'
import {
HeaderWrapper,
Logo,
Nav,
NavItem,
NavSearch,
Addition,
Button,
SearchWrapper
} from './style'
class App extends Component{
// state={
// focused:false
// }
focus=()=>{
this.setState({
focused:true
})
}
blur=()=>{
this.setState({
focused:false
})
}
render()
{
return(
<HeaderWrapper>
<Logo />
<Nav>
<NavItem className='left active'>首页 <span className='h'> 嗷嗷</span></NavItem>
<NavItem className='left'>下载App</NavItem>
<NavItem className='right'>登录</NavItem>
<NavItem className='right'>
<i className="iconfont"></i>
</NavItem>
<SearchWrapper>
<CSSTransition
in={this.props.state.get('focused')}
timeout={2000}
classNames="slide"
>
<NavSearch
className={this.props.state.get('focused') ? 'focused':''}
onFocus={this.props.handleInputFocus}
onBlur={this.props.handleInputBlur}
/>
</CSSTransition>
<i className={this.props.state.get('focused') ? 'focused iconfont zoom': 'iconfont zoom'}></i>
</SearchWrapper>
</Nav>
<Addition>
<Button className='writting'>
<i className="iconfont"></i>
写文章
</Button>
<Button className='reg'>注册</Button>
</Addition>
</HeaderWrapper>
)
}
}
const mapStateToProps=(state)=>{
return{
state:state.HeaderReducer
}
}
const mapDispatchToProps=(dispatch)=>{
return {
handleInputFocus()
{
return dispatch(action.searchFocus())
},
handleInputBlur()
{
return dispatch(action.searchBlur())
}
}
}
export default connect(state=>({state:state.HeaderReducer}),mapDispatchToProps)(App)