创建store仓库
1. 安装
npm i redux -S
2. 新建仓库入口文件 store/index.js
//index.js
import {createStore} from "redux" //引入createStore方法
const store=createStore()//创建数据存储仓库
export default store
3.新建reducer文件 store/reducer.js
//reducer.js
const defaultState={
inputValue:"",
list:[]
}//定义默认数据
export default (state=defaultState,action)=>{
return state
}
4.将reducer引入store
import {createStore} from "redux"
import reducer from "./reducer"
const store=createStore(reducer)
export default store
获取store仓库中的数据
1、引入store
import store from "./store"
2、在组件构造函数中赋值给state
constructor(props){
super(props)
this.state=store.getState()
console.log(this.state)
}
3、在组件模板中使用仓库中的值
{this.state.inputValue}
修改store仓库中的值
1.在组件的构造函数中订阅仓库改变的方法
constructor(props){
super(props)
this.state=store.getState()//赋值给组件state
this.storeChange=this.storeChange.bind(this)//修改this指向
store.subscribe(this.storeChange)//订阅store修改
}
storeChange(){
this.setState(store.getState())
}
2.创建action
要改变redux中的state的值,就要创建action了,action就是一个对象,一般有两个属性,第一个是action的类型描述,第二个是改改变的值
changeInput(){
const action={
type:'add',
value:e.target.value
}
}
3、通过dispatch()方法传递给store
changeInput(){
const action={
type:'add',
value:e.target.value
}
store.dispatch(action)
}
4、在reducer中接收传递过来的action
export default (state={defaultState,action})=>{
if(action.type=='add'){
const newState=JSON.parse(JSON.stringify(state))
newState.inputValue=action.value
return newState
}
return state
}
state:指的是原始仓库里的值
action:指的是action新传递的状态
reducer接收到传递过来的数据后,首先判断type是不是正确的,如果正确,我们需要声明一个变量newState,(reducer里面只能接收state,不能改变state),最后return返回新变量
到这里,redux的工作流程已经完成了,但是实际上还有很多需要优化的点。
1.使用actionTypes.js统一管理action中的type
//store/actionTypes.js
export const CHANGE_INPUT="change_input"
export const ADD_ITEM="addItem"
export const REMOVE_ITEM="removeIttem"
在所有定义action和reducer的地方,引入actionTypes,并替换相应的action type
import {CHANGE_INPUT,ADD_ITEM,REMOVE_ITEM} from './store/actionTypes'
changeInput(){
const action={
type:CHANGE_INPUT,
value:e.target.value
}
store.dispatch(action)
}
export default (state=defaultState,action)=>{
if(action.type==CHANGE_INPUT){
const newState=JSON.parse(JSON.stringify(state))
newState.inputValue=action.value
return newState
}
return state
}
2.使用actionCreators.js统一管理action
//store/actionCreators.js
export const chaangeInputAction=value=>({
type:CHANGE_INPUT,
value
})
export const addItemAction=()=>({
type:ADD_ITEM
})
export const removeItemAction=index=>({
type:REMOVE_ITEM,
index
})
- 改造组件中的action
changeInput(e){ const action=changeInputAction(e.taraget.value) sstore.dispatch(action) } addItem(){ const action=addItemAction() store.dispatch(aaction) } removeItem(index){ const action=removeItemAction(index) store.dispatch(action) }
Store必须是唯一的
在整个应用中,只在store/index中通过createStore()声明了一个store,之后整个应用都在使用这个store
只有store能改变自己的内容,reducer不能改变store的内容
虽然我们在reducer中处理业务逻辑,但是reducer中并不能改变store,我们只是在reducer中声明了一个新的state,最后返回给store。
所以reducer只是返回了更改的数据,但是并没有修改store中的数据,store拿到reducer传递的数据,自己对自己进行了修改
reducer必须是纯函数
如果函数的入参相同,函数返回的结果总是相同,就称为纯函数。它不依赖于程序执行过程中函数外部任何状态或者数据的改变,只依赖于函数的输入参数
简而言之,就是函数的返回结果是由传入的值决定的,而不是其他的东西决定的。
比如在reducer中增加一个异步ajax函数,获取后端接口数据,然后再返回,这是不允许的, 包括使用日期函数new Date()也是不允许的,因为不是纯函数了,违反了调用参数相同,返回相同的结果。