redux的使用
1.redux的使用
核心概念
action
-
动作的对象
-
包含2个属性
type:标识属性, 值为字符串, 唯一, 必要属性 data:数据属性, 值类型任意, 可选属性
-
例子:{ type: 'ADD_STUDENT',data:{name: 'tom',age:18} }
reducer
-
用于初始化状态、加工状态。
-
加工时,根据旧的state和action, 产生新的state的纯函数。
store
-
将state、action、reducer联系在一起的对象
-
如何得到此对象?
1) import {createStore} from 'redux' 2) import reducer from './reducers' 3) const store = createStore(reducer)
-
此对象的功能?
1) getState(): 得到state 2) dispatch(action): 分发action, 触发reducer调用, 产生新的state 3) subscribe(listener): 注册监听, 当产生了新的state时, 自动调用
求和案例使用redux
constant.js
/*
该模块是用于定义actions对象中type类型的常量值
*/
export const INCREMENT = 'increment'
export const DECREMENT = 'decrement'
count_action.js
/*
该文件专门为Count组件生成action对象
*/
import {INCREMENT, DECREMENT} from "./constant";
export const createIncrementAction = data => ({type: INCREMENT, data})
export const createDecrementAction = data => ({type: DECREMENT, data})
count_reducer.js
/*
1.该文件用于创建一个为Count组件服务的reducer,reducer的本质就是一个函数
2.reducer函数会接收到两个参数,分别为:之前的状态(preState),动作对象(action)
*/
import {INCREMENT, DECREMENT} from "./constant";
const initState = 0 //初始化状态,页面渲染时会自动调用一次
export default function countReducer(preState=initState, action) {
console.log(preState, action)
// 从action对象中获取type,data
const {type, data} = action
// 根据type决定如何加工数据
switch (type) {
case INCREMENT: // 如果是加
return preState + data;
case DECREMENT: // 如果是减
return preState - data;
default:
return preState
}
}
store.js
/*
该文件用于暴露一个store对象,整个应用只有一个store对象
*/
// 引入createStore, 专门用于创建redux中最核心的store对象
import {createStore} from "redux";
// 引入为Count组件服务的reducer
import count_reducer from "./count_reducer";
export default createStore(count_reducer)
index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import store from "./redux/store";
ReactDOM.render(<App />, document.getElementById('root'))
// 监测redux中状态的变化,只要变化,就调用render
store.subscribe(()=>{
ReactDOM.render(<App />, document.getElementById('root'))
})
Count.jsx
import React, {Component} from 'react';
// 引入store, 用于获取redux保存的状态
import store from "../../redux/store";
// 引入actionCreator, 专门用于创建action对象
import {createDecrementAction, createIncrementAction} from "../../redux/count_action";
class Count extends Component {
state = {count: 0}
// 第二种方法:第一种在index.js订阅
// componentDidMount() {
// // 监测redux中状态的变化,只要变化,就调用render
// store.subscribe(()=>{
// this.setState({})
// })
// }
increment = () => {
const {value} = this.selectNumber
store.dispatch(createIncrementAction(value*1))
}
decrement = () => {
const {value} = this.selectNumber
store.dispatch(createDecrementAction(value*1))
}
incrementOdd = () => {
const {value} = this.selectNumber
const count = store.getState()
if (count % 2 !== 0) {
store.dispatch(createIncrementAction(value*1))
}
}
incrementAsync = () => {
const {value} = this.selectNumber
setTimeout(() => {
store.dispatch(createIncrementAction(value*1))
}, 500)
}
render() {
return (
<div>
<h1>当前求和为: {store.getState()}</h1>
<select ref={c => this.selectNumber = c}>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button onClick={this.increment}>+</button>
<button onClick={this.decrement}>-</button>
<button onClick={this.incrementOdd}>当前求和为奇数加</button>
<button onClick={this.incrementAsync}>异步加</button>
</div>
);
}
}
export default Count;
异步action版
npm install --save redux-thunk (需安装使用异步中间件)
在store.js
中修该
import {createStore, applyMiddleware} from "redux";
// 引入redux-thunk,用于支持异步action
import thunk from "redux-thunk";
// applyMiddleware使用中间件
export default createStore(count_reducer, applyMiddleware(thunk))
在count_action.js
中修改
import {INCREMENT, DECREMENT} from "./constant";
// 同步action: 就是指action的返回值为Object类型的一般对象
export const createIncrementAction = data => ({type: INCREMENT, data})
export const createDecrementAction = data => ({type: DECREMENT, data})
// 异步action: 就是指action的返回值为函数,函数自动接收dispatch
// 异步action中一般都会调用同步action,异步action不是必须要用的
export const createIncrementAsyncAction = (data, time) => {
return (dispatch)=>{
setTimeout(()=>{
dispatch(createIncrementAction(data))
},time)
}
}