redux快速上手
用reflux存在问题
我们cmdb项目目前是用react reflux 进行构建的,使用起来非常方便
- 使用Plugin
reflux-state-mixin
可以快速地通过store.setState()
方法修改修改组件之间共享数据。 - 使用Plugin
reflux-promise
可以用action().then().catch()解决异步请求回调
当然在使用过程中也发现了一些问题
reflux允许多个入口修改store。
- action修改store
- store中的函数直接修改
- 直接setState
- 直接对reflux store 中定义的对象进行修改,无法修改成功。必须进行深拷贝
- 高阶组件无法避免重复render (react性能优化)
store定义混乱
- 列表数据跟子数据定义在一块
- 数据容易重复定义(圈子权限跟用户角色权限)
使用redux
为什么使用redux
- 公司其他项目逐渐改用redux
- redux 在react生态圈是使用最火的一个框架(之一)
- 使用redux 正好解决了上述问题
redux的优点
- 单一store 数据好管理
- 配合react-redux 可以将数据派发倒任何一个子组件
- 修改store的唯一方法是dispatch 一个action
step1:定义初始数据
开始定义一个component的初始数据会定义在getInitialState中
getInitialState(){
return {
list:[
{id:1,name:'数据1'},
{id:2,name:'数据2'},
{id:3,name:'数据3'},
]
}
}
使用redux定义初始数据需要定义在一个reducer中,通过一个函数返回需要得到的数据
const initialState =[
{id:1,name:'数据1'},
{id:2,name:'数据2'},
{id:3,name:'数据3'},
];
function reducer(state = initialState, action) {
return state
}
step2:创建store
通过redux的createStore方法创建唯一的store
const store = createStore(
reducer
)
step3: 安装react-redux
所有容器组件都可以访问 Redux store,可以使用React Redux 组件 <Provider> 来让所有容器组件都可以访问 store,
而不必显示地传递它。只需要在渲染根组件时使用即可。
import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import { createStore } from 'redux'
import reducer from './reducer'
import App from './components/App'
let store = createStore(reducer)
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
step4 component读取 state
定义 mapStateToProps 这个函数来指定如何把当前 Redux store state 映射到展示组件的 props 中。
import React from 'react'
import { connect } from 'react-redux'
let App=React.createClass({
render(){
const {list}=this.props;
return(
<div>
<ul>
{list.map((item)=><Item key={item.id} item={item}/>)}
</ul>
</div>
)
}
})
const mapStateToProps = (state) => {
return {
list: state
}
}
export default connect(
mapStateToProps,
)(App)
step5 通过action修改redux中的数据
export function deleteItem(id)=>{
return {
type:'DELETE_ITEM',
payload:{
id:id
}
};
}
const initialState =[
{id:1,name:'数据1'},
{id:2,name:'数据2'},
{id:3,name:'数据3'},
];
function reducer(state = initialState, action) {
switch (action.type) {
case 'DELETE_ITEM':
return state.filter(item=>
item.id !== action.payload.id
)
default:
return state
}
}
step6 分发 action
除了读取 state,connect()还能分发 action。可以定义 mapDispatchToProps() 方法,
接收 dispatch() 方法并返回期望注入到展示组件的 props 中的回调方法
import React from 'react';
import {deleteItem} from '../actions/index'
import { connect } from 'react-redux'
let App=React.createClass({
render(){
const {list,deleteItem}=this.props;
return(
<div>
<ul>
{list.map((item)=><Item key={item.id} deleteItem={deleteItem} item={item}/>)}
</ul>
</div>
)
}
})
const mapStateToProps = (state) => {
return {
list: state
}
}
const mapDispatchToProps = (dispatch) => {
return {
deleteItem: (id) => {
dispatch(deleteItem(id))
}
}
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(App)
import React from 'react'
let Item=React.createClass({
render(){
const {item}=this.props;
return(
<li>
{item.name}<button onClick={()=>this.props.deleteItem(item.id))}}>删除</button>
</li>
)
}
})
export default Item