1,什么是redux
Redux是一个用来治理治理数据状态和UI状态的JavaScript利用工具。随着JavaScript单页利用(SPA)开发日趋简单,JavaScript须要治理比任何时候都要多的state(状态),Redux就是升高治理难度的。(Redux反对React,Angular、jQuery甚至纯JavaScript)
react-redux工作流程
装置redux
npm install --save redux
简略应用
在src下新建store文件夹,创立仓库管理文件index.js
import { createStore, applyMiddleware, compose } from 'redux' // 引入createStore办法import reducer from "./reducer"const store = createStore(reducer) // 创立数据存储仓库export default store //裸露进来
同时创立reducer.js文件
//定义初始stateconst defaultState = { inputValue: '请输出待办事项', list: [ '早上4点起床,锻炼身体', '中午上班游泳一小时' ]}export default (state = defaultState, action) => { return state}
组件中应用state的值
import React, { Component } from 'react';//组件中引入storeimport store from './store'class TodoList extends Component { constructor(props) { super(props) #获取store中state的值 this.state = store.getState(); this.clickBtn = this.clickBtn.bind(this) } render() { return ( <div> <Input placeholder={this.state.inputValue} style={{ width: '250px', marginRight: '10px' }} value={this.state.inputValue} /> <Button type="primary" onClick={clickBtn}>减少</Button> </div> <div style={{ margin: '10px', width: '300px' }}> <List bordered dataSource={this.state.list} renderItem={(item, index) => (<List.Item onClick={() => { deleteItem(index) }}>{item}</List.Item>)}></List> </div> ); } deleteItem(index) { console.log(index) }}export default TodoList;
二,装置redux谷歌调试工具
翻墙下载redux_dev_tool,
在store/index文件下增加
import { createStore, applyMiddleware, compose } from 'redux' // 引入createStore办法import reducer from "./reducer"//const composeEnhancers = //const enhancers = composeEnhancers(applyMiddleware(thunk)) const store = createStore( reducer, window.__REDUX_DEVTOOLS_EXTENSION_ && window.__REDUX_DEVTOOLS_EXTENSION_() ) // 创立数据存储仓库,存在调试工具,开启工具export default store
三,操作store 扭转
import React, { Component } from 'react';//组件中引入storeimport store from './store'class TodoList extends Component { constructor(props) { super(props) #获取store中state的值 this.state = store.getState(); this.clickBtn = this.clickBtn.bind(this) this.changeInputValue = this.changeInputValue.bind(this) #增加订阅 #新版本不必增加订阅 然而input value变动须要应用订阅 store.subscribe(this.storeChange) this.storeChange = this.storeChange.bind(this) } render() { return ( <div> <Input placeholder={this.state.inputValue} style={{ width: '250px', marginRight: '10px' }} onChange={()=>{this.changeInputValue} value={this.state.inputValue} /> <Button type="primary" onClick={this.clickBtn}>减少</Button> </div> <div style={{ margin: '10px', width: '300px' }}> <List bordered dataSource={this.state.list} renderItem={(item, index) => ( <List.Item onClick={() => {deleteItem(index)}}>{item}</List.Item> )}></List> </div> ); } changeInputValue(e){ //申明action对象 const action ={ type:'changeInput', value:e.target.value } //调用dispatch store.dispatch(action) } // 订阅更新 storeChange() { this.setState(store.getState()) } // 增加按钮事件 clickBtn(){ const action ={ type:'addItem', } store.dispatch(action) } //点击删除事件 deleteItem(index) { const action = { type:'deleteItem', index } store.dispatch(action) }}export default TodoList;
在reducer.js中执行对应type类型的操作
//定义初始stateconst defaultState = { inputValue: '请输出待办事项', list: [ '早上4点起床,锻炼身体', '中午上班游泳一小时' ]}export default (state = defaultState, action) => { #reducer里只能承受state 不能扭转state if(action.type == 'changeInput'){ let newState = JSON.pares(JSON.stringify(state)) //深拷贝state newState.inputValue = action.value return newState } //增加事件 if(action.type == 'addItem'){ let newState = JSON.pares(JSON.stringify(state)) //深拷贝state newState.list.push(newState.inputValue) newState.inputValue = '' //减少实现,设置为空 return newState } //删除事件 if(action.type == 'deleteItem'){ let newState = JSON.pares(JSON.stringify(state)) //深拷贝state newState.list.splice(action.index,1) return newState } return state}
三,写redux的小技巧
- 独立type文件
在store中新建文件actionType.js
//定义常量export const CHANGE_INPUT = 'changeInput'export const ADD_ITEM = 'addItem'export const DELETE_ITEM = 'deleteItem'export const GET_LIST = 'getList'
在组件中引入actionType文件
import React, { Component } from 'react';//组件中引入storeimport store from './store'import { CHANGE_INPUT, ADD_ITEM, DELETE_ITEM, GET_LIST } from './store/actionType'class TodoList extends Component { constructor(props) { super(props) #获取store中state的值 this.state = store.getState(); this.clickBtn = this.clickBtn.bind(this) this.changeInputValue = this.changeInputValue.bind(this) #增加订阅 #新版本不必增加订阅 然而input value变动须要应用订阅 store.subscribe(this.storeChange) this.storeChange = this.storeChange.bind(this) } render() { return ( <div> <Input placeholder={this.state.inputValue} style={{ width: '250px', marginRight: '10px' }} onChange={()=>{this.changeInputValue} value={this.state.inputValue} /> <Button type="primary" onClick={this.clickBtn}>减少</Button> </div> <div style={{ margin: '10px', width: '300px' }}> <List bordered dataSource={this.state.list} renderItem={(item, index) => ( <List.Item onClick={() => {deleteItem(index)}}>{item}</List.Item> )}></List> </div> ); } changeInputValue(e){ //申明action对象 #应用引入的常量替换 const action ={ type:CHANGE_INPUT, value:e.target.value } //调用dispatch store.dispatch(action) } // 订阅更新 storeChange() { this.setState(store.getState()) } // 增加按钮事件 clickBtn(){ const action ={ type:ADD_ITEM, } store.dispatch(action) } //点击删除事件 deleteItem(index) { const action = { type:DELETE_ITEM, index } store.dispatch(action) }}export default TodoList;
在reducer.js中也进行引入
import { CHANGE_INPUT, ADD_ITEM, DELETE_ITEM } from './actionType'//定义初始stateconst defaultState = { inputValue: '请输出待办事项', list: [ '早上4点起床,锻炼身体', '中午上班游泳一小时' ]}export default (state = defaultState, action) => { #reducer里只能承受state 不能扭转state if(action.type == CHANGE_INPUT){ let newState = JSON.pares(JSON.stringify(state)) //深拷贝state newState.inputValue = action.value return newState } //增加事件 if(action.type == ADD_ITEM){ let newState = JSON.pares(JSON.stringify(state)) //深拷贝state newState.list.push(newState.inputValue) newState.inputValue = '' //减少实现,设置为空 return newState } //删除事件 if(action.type == DELETE_ITEM){ let newState = JSON.pares(JSON.stringify(state)) //深拷贝state newState.list.splice(action.index,1) return newState } return state}
- 集中整顿action派发
在store中新建actionCreator.js文件
import { CHANGE_INPUT, ADD_ITEM, DELETE_ITEM } from './actionType'export const changeInputAction = (value) =>({ type:CHANGE_INPUT, value})export const addItemAction = () =>({ type:ADD_ITEM,})export const deleteItemAction = (index) =>({ type:DELETE_ITEM, index})
在组件中引入actionCreator.js
import React, { Component } from 'react';//组件中引入storeimport store from './store'//引入actionCreator.jsimport { changeInputAction,addItemAction,deleteItemAction } from './store/actionCreator'class TodoList extends Component { constructor(props) { super(props) #获取store中state的值 this.state = store.getState(); this.clickBtn = this.clickBtn.bind(this) this.changeInputValue = this.changeInputValue.bind(this) #增加订阅 #新版本不必增加订阅 然而input value变动须要应用订阅 store.subscribe(this.storeChange) this.storeChange = this.storeChange.bind(this) } render() { return ( <div> <Input placeholder={this.state.inputValue} style={{ width: '250px', marginRight: '10px' }} onChange={()=>{this.changeInputValue} value={this.state.inputValue} /> <Button type="primary" onClick={this.clickBtn}>减少</Button> </div> <div style={{ margin: '10px', width: '300px' }}> <List bordered dataSource={this.state.list} renderItem={(item, index) => ( <List.Item onClick={() => {deleteItem(index)}}>{item}</List.Item> )}></List> </div> ); } changeInputValue(e){ const action = changeInputAction(e.target.value) //调用dispatch store.dispatch(action) } // 订阅更新 storeChange() { this.setState(store.getState()) } // 增加按钮事件 clickBtn(){ const action =addItemAction() store.dispatch(action) } //点击删除事件 deleteItem(index) { const action = deleteItemAction(index) store.dispatch(action) }}export default TodoList;