您当前的位置: 首页 > 

知其黑、受其白

暂无认证

  • 0浏览

    0关注

    1250博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

P07:通过Input体验Redux的流程

知其黑、受其白 发布时间:2021-12-14 12:23:26 ,浏览量:0

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 的整体流程,是如何编写代码的。我们要实现的是在 TodoListDemo 中,只要文本框中的值改变就 reduxstore 的值就跟着改变,并且随着 Redux 中的 state 值改变,组件也跟着改变。

整个流程就是以前讲过的这个图: 在这里插入图片描述

增加 Input 响应事件

如果想 Input 改变,redux 也跟着改变,需要在 Input 组件上增加 onChange 响应事件, 打开 src 目录下的 ToDolist.js 文件,修改具体代码如下:


写完这一步,还要记得在 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 ( 
            
                
                    
                    增加
                
                
                    ({item})}
                    />    
                
            
         );
    }

    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组件。

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(,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 ( 
            
                
                    
                    增加
                
                
                    ({item})}
                    />    
                
            
         );
    }

    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
}
关注
打赏
1665558895
查看更多评论
立即登录/注册

微信扫码登录

0.0441s