首页 > 其他分享 >P07:通过Input体验Redux的流程

P07:通过Input体验Redux的流程

时间:2023-02-09 11:33:15浏览次数:51  
标签:12 state P07 import action Input Redux store


Redux基础

  • ​​阐述​​
  • ​​增加 Input 响应事件​​
  • ​​源码​​
  • ​​创建 Action​​
  • ​​store 的自动推送策略​​
  • ​​让组件发生更新​​
  • ​​总结​​
  • ​​demo​​
  • ​​初始化项目​​
  • ​​安装 Ant Design UI组件​​
  • ​​Chrome 安装插件 Redux-DevTools​​
  • ​​安装 Redux 是JavaScript应用工具​​
  • ​​创建 Redux​​
  • ​​项目目录结构​​
  • ​​demo01\src\index.js​​
  • ​​demo01\src\TodoList.js​​
  • ​​demo01\src\store\index.js​​
  • ​​demo01\src\store\reducer.js​​

阐述

本文将要带大家作的就是通过 ​​Input​​​ 的改变,体验一下 ​​Redux​​​ 的整体流程,是如何编写代码的。我们要实现的是在 ​​TodoList​​​ 的 ​​Demo​​​ 中,只要文本框中的值改变就 ​​redux​​​ 中 ​​store​​​ 的值就跟着改变,并且随着 ​​Redux​​​ 中的 ​​state​​ 值改变,组件也跟着改变。

整个流程就是以前讲过的这个图:

P07:通过Input体验Redux的流程_react.js

增加 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​​ 看一下控制台的结果。

P07:通过Input体验Redux的流程_react.js_02


下面需要作的事就是改变 ​​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
}

P07:通过Input体验Redux的流程_List_03

让组件发生更新

现在 ​​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调试工具

P07:通过Input体验Redux的流程_前端_04

安装 Redux 是JavaScript应用工具

Redux是一个用来管理数据状态和UI状态的JavaScript应用工具。

在使用Redux之前,需要先用 npm install 来进行安装,打开终端,并进入到项目目录,然后输入。

​npm install --save redux react-redux​

P07:通过Input体验Redux的流程_前端_05

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
}


标签:12,state,P07,import,action,Input,Redux,store
From: https://blog.51cto.com/u_13571520/6046471

相关文章