P07:通过Input体验Redux的流程
Posted wgchen~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P07:通过Input体验Redux的流程相关的知识,希望对你有一定的参考价值。
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)
然后打开浏览器,按F 12
看一下控制台的结果。
下面需要作的事就是改变 Redux
里的值了,我们继续向下学习。
源码
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;
创建 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入门了。
可以把本文内容多看两遍,保证把基础知识打扎实,更重要的是一定要动手作,不然你真的学不会的。
demo
初始化项目
1 如果你没有安装脚手架工具,你需要安装一下:
npm install -g create-react-app
2 直接用脚手架工具创建项目
D: 进入D盘
mkdir ReduxDemo 创建ReduxDemo文件夹
cd ReduxDemo 进入文件夹
create-react-app demo01 用脚手架创建React项目
cd demo01 等项目创建完成后,进入项目目录
npm start 预览项目
删除 src
里边的所有文件,只留一个 index.js,并且 index.js
文件里也都清空。
安装 Ant Design UI组件
Ant Design 是一套面向企业级开发的UI框架,视觉和动效作的很好。
安装 AntDesign
npm install antd --save
在使用Ant Design时,第一件事就是先引入CSS样式,有了样式才可以让UI组件显示正常。
import 'antd/dist/antd.css'
引入CSS样式之后,可以快乐的使用 antd 里的 <input>
框了,在使用的时候,你需要先引入Input组件。
import Input from 'antd'
Chrome 安装插件 Redux-DevTools
安装 Chrome 插件 Redux-DevTools – Redux调试工具
安装 Redux 是javascript应用工具
Redux是一个用来管理数据状态和UI状态的JavaScript应用工具。
在使用Redux之前,需要先用 npm install 来进行安装,打开终端,并进入到项目目录,然后输入。
npm install --save redux react-redux
Redux有3大核心概念:
- Action
- Reducer
- Store
Action 和 Store 都非常好理解,我们可以直接按照其字面意思,将他们理解为 动作
和 储存
。
Action表示应用中的各类动作或操作,不同的操作会改变应用相应的state状态,说白了就是一个带type属性的对象。
Store则是我们储存state的地方。
我们通过redux当中的createStore方法来创建一个store,它提供3个主要的方法:
import createStore from 'redux' // 引入createStore方法
const store = createStore() // 创建数据存储仓库
export default store //暴露出去
建立好了仓库,但是这个仓库很混乱,这时候就需要一个有管理能力的模块出现,这就是 Reducers。这两个一定要一起创建出来,这样仓库才不会出现互怼现象。
Reducer里更新Store里的state,Reducer接收两个参数:
旧的 state 和 Action,返回一个新的 state,即 (state, action) => newState
。
创建 Redux
安装好redux之后,在 src
目录下创建一个 store
文件夹,然后在文件夹下创建一个 index.js
文件。
D:\\ReactDemo\\demo01\\src\\store\\index.js 就是整个项目的 store 文件
D:\\ReactDemo\\demo01\\src\\store\\index.js
// 引入createStore方法
import createStore from 'redux'
// reducer就建立好了后引入到 store 中,再创建 store 时,以参数的形式传递给 store。
import reducer from './reducer'
// 创建数据存储仓库
const store = createStore(
reducer,
// 配置 Redux Dev Tools
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
)
export default store //暴露出去
建立好了仓库,就需要 Reducers 管理模块。
D:\\ReactDemo\\demo01\\src\\store\\reducer.js
const defaultState = //默认数据
export default (state = defaultState,action)=> //就是一个方法函数
return state
state
: 是整个项目中需要管理的数据信息
项目目录结构
d/ReactDemo/demo01 (master)
$ ls -al
total 1921
drwxr-xr-x 1 Administrator 197121 0 12月 7 11:32 ./
drwxr-xr-x 1 Administrator 197121 0 12月 7 11:31 ../
drwxr-xr-x 1 Administrator 197121 0 12月 7 11:32 .git/
-rw-r--r-- 1 Administrator 197121 310 12月 7 11:31 .gitignore
drwxr-xr-x 1 Administrator 197121 0 12月 13 18:31 node_modules/
-rw-r--r-- 1 Administrator 197121 948 12月 13 18:31 package.json
-rw-r--r-- 1 Administrator 197121 1547406 12月 13 18:31 package-lock.json
drwxr-xr-x 1 Administrator 197121 0 12月 7 11:32 public/
-rw-r--r-- 1 Administrator 197121 3369 12月 7 11:31 README.md
drwxr-xr-x 1 Administrator 197121 0 12月 13 18:12 src/
d/ReactDemo/demo01/src/store (master)
$ ls -al
total 6
drwxr-xr-x 1 Administrator 197121 0 12月 13 18:14 ./
drwxr-xr-x 1 Administrator 197121 0 12月 13 18:12 ../
-rw-r--r-- 1 Administrator 197121 281 12月 13 19:14 index.js
-rw-r--r-- 1 Administrator 197121 430 12月 14 10:41 reducer.js
demo01\\src\\index.js
主文件
import React from 'react';
import ReactDOM from 'react-dom' // 上面两必有
import TodoList from './TodoList'
ReactDOM.render(<TodoList/>,document.getElementById('root'))
demo01\\src\\TodoList.js
组件
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)
//----------关键代码-----------start
this.storeChange = this.storeChange.bind(this) //转变this指向
store.subscribe(this.storeChange) //订阅Redux的状态
//----------关键代码-----------end
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)
const action =
type:'change_input_value',
value:e.target.value
store.dispatch(action)
storeChange()
this.setState(store.getState())
export default TodoList;
demo01\\src\\store\\index.js
store 仓库
// 引入createStore方法
import createStore from 'redux'
import reducer from './reducer'
// 创建数据存储仓库
const store = createStore(reducer,window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__())
//暴露出去
export default store
demo01\\src\\store\\reducer.js
const defaultState =
inputValue : 'Write Something',
list:[
'早上4点起床,锻炼身体',
'中午下班游泳一小时'
]
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
以上是关于P07:通过Input体验Redux的流程的主要内容,如果未能解决你的问题,请参考以下文章