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文件
//定义初始state
const defaultState = {
inputValue: '请输入待办事项',
list: [
'早上4点起床,锻炼身体',
'中午下班游泳一小时'
]
}
export default (state = defaultState, action) => {
return state
}
组件中使用state的值
import React, { Component } from 'react';
//组件中引入store
import 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';
//组件中引入store
import 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类型的操作
//定义初始state
const 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';
//组件中引入store
import 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'
//定义初始state
const 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';
//组件中引入store
import store from './store'
//引入actionCreator.js
import { 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;
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。