今天开始学习redux咯----核心---reducer
redux:本质js库,状态容器,使react(view)+redux(state)完美解耦/数据传递。支持中间件机制
一个组件树中,传值时可以利用store中的所有state连接起来。
react做视图层的开发,大型应用的话可能会很复杂。
需求:大型应用需要组件视图 + 集中式管理的store + 组件路由管理 + 网络请求管理。
大致流程图如下:
先不搞那么复杂,先来第一步,不涉及网络请求实验一下。
经典老番---增加减少
创建一个react项目,其中的App.js就是所谓的view视图层,创建一个新的文件夹store,里面包含index.js和reducer.js,他们两个不分家,代码都在reducer.js中写好,在store中引用就完了,可以说reducer就是工具人,成果全部让store抢走咯,因为view引入的最终还是store-index.js。
import { Component } from "react";
import store from "./store";
class App extends Component{
constructor(){
super();
this.state={count:0}
this.increament=()=>{
}
this.decrement=()=>{
}
}
render() {
return(
<div >
<p>Clicked:{this.state.count} times</p>
<button onClick={this.increament}>++++</button>
<button onClick={this.decrement}>----</button>
</div>
)
}
}
export default App;
初始页面便是如此,写好点击事件等着引用store中的事件。
进入reducer页面:设置初始值:const defaultState = 0
初始值:可以是js中任何有效值,建议用对象的形式。
reducer是一个纯函数,有两个参数,分别是上一次的状态与进行的action,又通过去判断action.type去选择下一步进行的操作。更新的条件是return新的state(新的地址)
const reducer = (state = defaultState, action) => {
switch (action.type) {
case 'INCREAMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
break;
}
}
export default reducer;
如果type是增加那就状态+1,是减少那就-1.记得导出给store用
store代码:
import {createStore} from "redux"
import reducer from "./reducer"
const store = createStore(reducer) //窃取果实
export default store
现在状态,与方法都在store中了,可以在view的App中引入store并使用方法了。
获取默认值;
this.state={count:store.getState()}
view要通过dispatch去调用store中的type:
this.increament=()=>{
store.dispatch({type:'INCREAMENT'})
}
this.decrement=()=>{
store.dispatch({type:'DECREMENT'})
}
以上,成功将方法注入view中了,通过测试后发现,状态竟然没有改变。
解决方法:同步store中的状态
store.subscribe(this.syncState)//订阅
syncState=()=>{
this.setState({count:store.getState()})
}
同步订阅一下,就可以啦。
优化:view层与reducer层
创建action用来单独存储数据名称,CONTENT方便集中式管理。
再创建actionCreator用于与action的type属性连接起来。
CONTANT.JS
export const INCREAMENT = 'INCREAMENT'
export const DECREMENT = 'DECREMENT'
actionCreator.js
import * as CONSTANT from "./constant" //引入contant
export const increamentAction = ()=>{
return {type:CONSTANT.INCREAMENT} //设置action的type属性
}
export const decrementAction = ()=>{
return {type:CONSTANT.DECREMENT}
}
这样也可以将reducer中涉及到的action.type统一更改为CONTENT中的名称了。
import * as CONSTANT from "../action/constant"
const defaultState = 0
const reducer = (state = defaultState, action) => {
switch (action.type) {
case CONSTANT.INCREAMENT:
return state + 1
case CONSTANT.DECREMENT:
return state - 1
default:
break;
}
}
export default reducer;