P07:Redux基础-通过Input体验Redux的流程
本文将要带大家作的就是通过Input
的改变,体验一下Redux
的整体流程,是如何编写代码的。我们要实现的是在TodoList
的 Demo 中,只要文本框中的值改变就redux
中store
的值就跟着改变,并且随着Redux
中的state
值改变,组件也跟着改变。整个流程就是以前讲过的这个图,
增加 Input 响应事件
如果想Input
改变,redux
也跟着改变,需要在Input
组件上增加onChange
响应事件, 打开src
目录下的ToDolist.js
文件,修改具体代码如下:
<Input placeholder={this.state.inputValue} style={{ width:'250px', marginRight:'10px'}} //---------关键代码----start onChange={this.changeInputValue} //---------关键代码----end />
写完这一步,还要记得在constructor
进行this
的绑定,修改this
的指向。
constructor(props){ super(props) this.state=store.getState(); this.changeInputValue= this.changeInputValue.bind(this) }
这步完成后,就可以编写changeInputValue
方法的代码了。我们先在控制台打印出文本框的变化,代码如下:
changeInputValue(e){ console.log(e.target.value) }
然后打开浏览器,按F12
看一下控制台的结果。
这里给出目前的全部代码:
import React, { Component } from 'react'; import 'antd/dist/antd.css' import { Input , Button , List } from 'antd' import store from './store' class TodoList extends Component { constructor(props){ super(props) this.state=store.getState(); this.changeInputValue= this.changeInputValue.bind(this) } render() { return ( <div style={{margin:'10px'}}> <div> <Input placeholder={this.state.inputValue} style={{ width:'250px', marginRight:'10px'}} onChange={this.changeInputValue} /> <Button type="primary">增加</Button> </div> <div style={{margin:'10px',width:'300px'}}> <List bordered dataSource={this.state.list} renderItem={item=>(<List.Item>{item}</List.Item>)} /> </div> </div> ); } changeInputValue(e){ console.log(e.target.value) } } export default TodoList;
下面需要作的事就是改变Redux
里的值了,我们继续向下学习。
创建 Action
想改变Redux
里边State
的值就要创建Action
了。Action 就是一个对象,这个对象一般有两个属性,第一个是对Action
的描述,第二个是要改变的值。
changeInputValue(e){ const action ={ type:'change_input_value', value:e.target.value } }
action 就创建好了,但是要通过dispatch()
方法传递给store
。我们在 action 下面再加入一句代码。
changeInputValue(e){ const action ={ type:'changeInput', value:e.target.value } store.dispatch(action) }
这是Action
就已经完全创建完成了,也和store
有了联系。
store 的自动推送策略
前面的课程,我已经说了store
只是一个仓库,它并没有管理能力,它会把接收到的action
自动转发给Reducer
。我们现在先直接在Reducer
中打印出结果看一下。打开store
文件夹下面的reducer.js
文件,修改代码。
export default (state = defaultState,action)=>{ console.log(state,action) return state }
讲到这里,就可以解释一下两个参数了:
- state: 指的是原始仓库里的状态。
- action: 指的是 action 新传递的状态。
通过打印你可以知道,Reducer
已经拿到了原来的数据和新传递过来的数据,现在要作的就是改变 store 里的值。我们先判断type
是不是正确的,如果正确,我们需要从新声明一个变量newState
。(记住:Reducer 里只能接收 state,不能改变 state。),所以我们声明了一个新变量,然后再次用return
返回回去。
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 }
让组件发生更新
现在 store 里的数据已经更新了,但是组件还没有进行更新,我们需要打开组件文件TodoList.js
,在constructor
,写入下面的代码。
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()) }
现在浏览器中预览,可以看到组件和 Redux 中都同步进行了改变。
总结
本文内容比较多,把 Redux 的流程都走了一遍,如果这节课你能独立作下来,也就算 Redux 入门了。你可以把本文内容多看两遍,保证把基础知识打扎实,更重要的是一定要动手作,不然你真的学不会的。
码云笔记 » P07:Redux基础-通过Input体验Redux的流程