最近接盘了一个react项目,对于没有接触过react项目的我,慌的不行。花费了一天的时间来看了react.js的文档后,开始了写react项目。在项目的过程中,传递数据真的太痛苦了,特别对于深层次组件,例如我写的一个酷我播放器页面,简直惨不忍睹,一个组件几十个数据,方法的传入,显得项目不可直视,为了赶进度也没有管,现在告一段落后,来学习了一下redux状态管理!分享写经验!
git地址:https://gitee.com/xieyong1234/redux-study.git
对于官网的描述,我就不再复述,直接先上代码结构,我对redux的结构进行的拆分。

redux的结构无外乎就是store,state,action, reducer来组成整个数据的修改与传递。简单的来描述redux的执行过程:
1:组件出发action来告知store你所要做的事情,
2:store通过reducer来处理对应的事件,reducer返回新的完整的state对象;
3:store接受reducer返回的对象更新state;
4:store将新的值传递给组件完成视图的更新
先来说下redux的执行细节及对应的api:
1.组件通过store的dispatch方法来传递action,store.dispatch(action);
2.reducer根据action来判断执行操作,返回完整的新对象,
3.store通过subscribe方法来监听state的变化,通知页面更新。store.subscribe(function(){});
4.更新函数通过setState()来出发视图刷新,页面的数据通过store.getState()来获取整个state
现在来贴上每个对应文件的代码,便于理解
入口文件:
import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; import * as serviceWorker from './serviceWorker'; ReactDOM.render( <App />, document.getElementById('root') ); serviceWorker.unregister();
组件文件:
import React,{ Component } from 'react';
import "antd/dist/antd.css";//antd的ui
import { Input, Button, List, Checkbox } from 'antd';
//引入自己定义好的action创建函数(为了拆分,便于维护)
import { changeInput, add_todo_item, delete_todo_item, check_box_handler, census_check_num, delete_completed } from './store/actionCreators';
import store from './store/'; //引入store
class App extends Component {
constructor(props){
super(props);
this.state = store.getState();//将store的state
this.handleInputChange = this.handleInputChange.bind(this);
this.updateState = this.updateState.bind(this);
this.addTodoItem = this.addTodoItem.bind(this);
this.deleteChecked = this.deleteChecked.bind(this);
store.subscribe(this.updateState)//监听store里state的更新
}
updateState(){
this.setState(store.getState());//出发视图更新
}
handleInputChange(e){ //input输入框的数据变化
store.dispatch(changeInput(e.target.value));//调用dispatch方法,传入对应的action来改变state
}
addTodoItem(){ //添加
store.dispatch(add_todo_item());
}
deleteTodoItem(index){ //删除一项todo
store.dispatch(delete_todo_item(index));
this.censucNum()
}
checkboxHandler(index){ //选中checkbox
store.dispatch(check_box_handler(index));
this.censucNum();
}
censucNum(){ //统计选中数量
store.dispatch(census_check_num());
}
deleteChecked(){ //删除所有选中
store.dispatch(delete_completed());
this.censucNum();
}
render() {
const { value, list, activeNum } = this.state;
return <div style={{maringTop:'10px',marginLeft:'10px'}}>
<Input value={value} onChange={this.handleInputChange} placeholder="todo info" style={{'300px',marginRight:'10px'}}/>
<Button type="primary" onClick={this.addTodoItem}>submit</Button>
<List
style={{'300px',marginTop:'10px'}}
bordered
dataSource={list}
renderItem={(item,index) => (<List.Item style={{position:'relative'}}><Checkbox checked={item.isCompleted} onChange={this.checkboxHandler.bind(this,index)} style={{marginRight:'10px'}}></Checkbox><div style={item.isCompleted ? {textDecoration:'line-through',color:'#ccc'} : {}}>{item.name}</div><div onClick={this.deleteTodoItem.bind(this,index)} style={{position:'absolute',right:'10px',top:'50%',transform:'translateY(-50%)',cursor:'pointer','20px',heigth:'20px',border:'1px solid #ccc',borderRadius:'50%',textAlign:'center',lineHeight:'20px'}}>X</div></List.Item>)}
/>
<div style={{'300px',height:'50px',display:'flex',justifyContent:'space-around',alignItems:'center',border:'1px solid #ccc',marginTop:'10px',borderRadius:'3px'}}>
<span>{activeNum}item</span>
<span onClick={this.deleteChecked} style={{cursor:'pointer'}}>delete completed</span>
</div>
</div>
}
}
export default App;
store文件:index.js
import { createStore } from 'redux'; //引入redux的函数,创建store
import reducer from './reducers'; //引入写好的reducer,注入store
const store = createStore(
reducer,
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()//应用于谷歌的redux'插件
);
export default store;
action的type类型:actionTypes.js
export const CAHNGE_INPUT_VALUE = 'change_input_value'; export const ADD_TODO_ITEM = 'add_todo_item'; export const DELETE_TODO_ITEM = 'delete_todo_item'; export const CHECK_BOX_HANDLER = 'check_box_helder'; export const CENSUS_CHECK_NUM = 'census_check_num'; export const DELETE_COMPLETED = 'delete_completed';
action的创建函数:cactionCreators.js
import { CAHNGE_INPUT_VALUE, ADD_TODO_ITEM, DELETE_TODO_ITEM, CHECK_BOX_HANDLER, CENSUS_CHECK_NUM, DELETE_COMPLETED } from './actionTypes';
export const changeInput = (value) => { //input框的创建函数,传入输入值,返回对应的action
return {
type: CAHNGE_INPUT_VALUE,
value
}
}
export const add_todo_item = () => {
return {
type:ADD_TODO_ITEM
}
}
export const delete_todo_item = (index) => {
return {
type:DELETE_TODO_ITEM,
index
}
}
export const check_box_handler = (index) => {
return {
type:CHECK_BOX_HANDLER,
index
}
}
export const census_check_num = () => {
return {
type:CENSUS_CHECK_NUM
}
}
export const delete_completed = () => {
return {
type:DELETE_COMPLETED
}
}
reducer文件:reducers.js
import { CAHNGE_INPUT_VALUE, ADD_TODO_ITEM, DELETE_TODO_ITEM, CHECK_BOX_HANDLER, CENSUS_CHECK_NUM, DELETE_COMPLETED } from './actionTypes'; const initState = { //state的默认值 value:'', list:[ { name:'1', isCompleted:false } ], activeNum:0 } export default (state=initState,action) => { //切记,reducer是一个纯函数,即输入条件相同,则输入一定相同,且不能有负面的影响;reducer中不能改变state let newState; switch(action.type){ case CAHNGE_INPUT_VALUE: return Object.assign({},state,{value:action.value}); case ADD_TODO_ITEM: newState = JSON.parse(JSON.stringify(state)); if(newState.value.trim() === '') return newState; newState.list.push({name:newState.value,isCompleted:false}); newState.value = ''; return newState; case DELETE_TODO_ITEM: newState = JSON.parse(JSON.stringify(state)); newState.list.splice(action.index,1); return newState; case CHECK_BOX_HANDLER: newState = JSON.parse(JSON.stringify(state)); newState.list[action.index].isCompleted = !newState.list[action.index].isCompleted; return newState; case CENSUS_CHECK_NUM: newState = JSON.parse(JSON.stringify(state)); let num=0; newState.list.forEach(element => { if(element.isCompleted) num++ }); return Object.assign({},state,{activeNum:num}); case DELETE_COMPLETED: newState = JSON.parse(JSON.stringify(state)); for(var i = newState.list.length-1;i>=0;i-- ){ var item = newState.list[i] if(item.isCompleted){ newState.list.splice(i,1) } } return newState; default: return state } }
至此,一个简单的redux项目就已经完成,效果如图:

redux和react并没有直接的关联,他也可以用在jq,js, ang中。现在初步的了解了redux后,可能你也发现他用起来不怎么好用,需要手动更新视图等,现在提供了一个react-redux来配合redux完成一个完整的状态管理机制。且结构更加清晰,组件化更极致。react被区分为视图ui组件和容器组件,ui展示组件只负责静态的视图层面,所有的数据,方法操作全部都在容器组件中完成,通过react-redux提供的几个方法,完成更好的实现方式!我将在下一次更新除react-redux的用法,同一个例子,到时候可以自行看到区别和用法!只要静下心,其实也都很容易理解,虽然感觉react非常复杂,难用,由于jsx的应用,使得项目写起来更费时费力,但他的结构,组件化更清晰!期待下次的更新