1 .安装redux
npm install --save redux
2 .在store中新建index.js和reducer.js
- index.js
import { createStore } from 'redux' // 引入createStore方法
import reducer from './reducer'
const store = createStore(reducer) // 创建数据存储仓库
export default store //暴露出去
- reducer.js
const defaultState = {} //默认数据
export default (state = defaultState,action)=>{ //就是一个方法函数
return state
}
3.初始话store的数据
- 在reducer.js中更改
const defaultState = {
inputValue : 'Write Something',
list:[
'早上4点起床,锻炼身体',
'中午下班游泳一小时'
]
}
export default (state = defaultState,action)=>{
return state
}
4 .组件中获取store中的数据
- 先引入
import store from './store'
- 看下打印结果,store.getState就是了
这时候数据还不能在UI层让组件直接使用,我们可以直接复制给组件的state,
constructor(props){
super(props)
console.log(store.getState())
this.state=store.getState();
}
5.更改store
- 使用input更改值
<input onChange={this.changeInputValue}
- 绑定
constructor(props){
super(props)
this.state=store.getState();
this.changeInputValue= this.changeInputValue.bind(this)
}
- 编写函数,想要更改state,就是需要创建Action,他是一个对象,有两个属性,第一个是对Action的描述,第二个是要改变的值,通过dispatch()传递个store
changeInputValue(e){
console.log(e.target.value)
const action ={
type:'change_input_value',
value:e.target.value
}
store.dispatch(action)
}
6 .在store中接收
前面的课程说了store只是一个仓库,不具备管理能力,他会把接收到action自动转发给reducer,我们在reducer.js打印一下,看下结果
export default (state = defaultState,action)=>{
console.log(state,action)
return state
}
- state: 指的是原始仓库里的状态。
- action: 指的是action新传递的状态。
-通过打印你可以知道,Reducer已经拿到了原来的数据和新传递过来的数据,现在要作的就是改变store里的值。我们先判断type是不是正确的,如果正确,我们需要从新声明一个变量newState。(记住:Reducer里只能接收state,不能改变state。),所以我们声明了一个新变量,然后再次用return返回回去。
Reducer.js
export default (state = defaultState,action)=>{
if(action.type === 'changeInput'){
let newState = JSON.parse(JSON.stringify(state)) //深度拷贝state
newState.inputValue = action.value
return newState
}
return state
}
7.让组件发生变化
在组件中写入
constructor(props){
super(props)
this.state=store.getState();
this.changeInputValue= this.changeInputValue.bind(this)
//----------关键代码-----------start
this.storeChange = this.storeChange.bind(this) //转变this指向
store.subscribe(this.storeChange) //订阅Redux的状态
//----------关键代码-----------end
}
- 当然我们现在还没有这个storeChange方法,只要写一下这个方法,并且重新setState一次就可以实现组件也是变化的。在代码的最下方,编写storeChange方法。
storeChange(){
this.setState(store.getState())
}
8. 更改store文件结构,让结构更加明确
- 1 .可以把action type单独拆成一个文件actionTypes.js文件
export const CHANGE_INPUT = 'changeInput'
- 写好了ationType.js文件,可以引入到TodoList.js组件当中,引入代码如下:
import { CHANGE_INPUT } from './store/actionTypes'
- 可以在下面的代码中代替他们
changeInputValue(e){
const action ={
type:CHANGE_INPUT,
value:e.target.value
}
store.dispatch(action)
}
- 在引入Reducer.js
import {CHANGE_INPUT} from './actionTypes'
const defaultState = {
inputValue : 'Write Something',
list:[
'早上4点起床,锻炼身体',
'中午下班游泳一小时'
]
}
export default (state = defaultState,action)=>{
if(action.type === CHANGE_INPUT){
let newState = JSON.parse(JSON.stringify(state)) //深度拷贝state
newState.inputValue = action.value
return newState
}
return state
}
9.继续优化
- 在新建一个actionCreate.js文件,将那个type文件引入
import {CHANGE_INPUT} from './actionTypes'
// 再写上
export const changeInputAction = (value)=>({
type:CHANGE_INPUT,
value
})
- 那样就可以直接组件中引入的type那个文件取代了,变成引入这个actionCreate.js文件
import {changeInputAction} from './store/actionCreatores'
那那个方法也就可以变为
changeInputValue(e){
const action = changeInputAction(e.target.value)
store.dispatch(action)
}
// 这是最早的样子
//changeInputValue(e){
// console.log(e.target.value)
// const action ={
// type:'change_input_value',
// value:e.target.value
// }
// store.dispatch(action)
}