redux好难懂,终于明白了一点,做了个小demo,记录一下。

先看目录结构:

src

|--index.js

|--actions

|--index.js

|--components

|--Additem.js

|--App.js

|--ItemList.js

|--reducers

|--index.js

最终效果如图:

redux三大件:actions , reducers, store ,

Action 是把数据从应用(译者注:这里之所以不叫 view 是因为这些数据有可能是服务器响应,用户输入或其它非 view 的数据 )传到 store 的有效载荷。它是 store 数据的唯一来源。一般来说你会通过store.dispatch() 将 action 传到 store。

这是官方的解释,我个人的理解是 action就是定义一个事件,但不做任何逻辑上的操作,只是把你需要处理的数据和事件绑定到一起,然后等待store进行派发,也就是更新store。就好像定义了一个按钮的点击事件 ;

btn.addEventListener(MouseEvent.CLICK,onClickHandle);

这句代码实际上什么操作也没有做,只是告诉系统有MouseEvent.CLICK消息的时候应该做什么。

reducer Action 只是描述了有事情发生了这一事实,并没有指明应用如何更新 state。而这正是 reducer 要做的事情。

这是官方解释,我的理解是就像上面说的onClickHandle函数,就是在等待事件被触发的时候要执行的代码,当有action被派发出来的时候,store就会根据定义来找到这个函数去执行,然后改变store,从而引起react的重新渲染,最终使view发生改变。

Store 就是把action 和 reducer 联系到一起的对象。Store 有以下职责:

  • 维持应用的 state;

  • 提供 getState() 方法获取 state;

  • 提供 dispatch(action) 方法更新 state;

  • 通过 subscribe(listener) 注册监听器。

Redux 应用只有一个单一的 store。当需要拆分处理数据的逻辑时,使用 reducer 组合 而不是创建多个 store。

我的理解是store就是一个事件监听器加事件派发器加状态记录器。他会根据被触发的action来找到对应的reducer。

我在写这个demo的时候是先定义了action,也就是会有哪些操作,然后根据这些action去写reducer,也就是每个事件应该怎么处理。最后写了界面,当然,也可以先写界面,根据界面定义action。

下面看看代码是怎么写的,很简单并且很简陋的一段代码,

src/actions/index.js:

"use strict";export const ADD_ITEM = 'add_item';
export const DEL_ITEM = 'delete_item';export function addItem(text){return {type:ADD_ITEM,text}
}export function delItem(index){return {type:DEL_ITEM,index}
}

这里定义了两个事件,一个是添加记录,一个是删除记录,每个方法都是返回一个对象,对象中必须有type属性,这个type属性实际上才是真正的事件区分器,

然后additem中的text是要添加记录的内容,index是要删除记录的所引。到这,action就完了。

reducers/index.js:

"use strict";import { combineReducers } from 'redux';
import { ADD_ITEM, DEL_ITEM } from '../actions/index';const initalState = {items:[]
};function aitems(state=[],action){switch (action.type){case ADD_ITEM:return state.concat([action.text]);case DEL_ITEM:state.splice(action.index,1);return [...state];default:return state;}
}let todos=combineReducers({items:aitems
});
export default todos;

这个文件里的内容就是根据action做的操作,通过type来区分发生了什么事,当应该添加一条记录的时候,就把text内容保存到数组中并返回,

这里有几点需要说明:

1,initalState{} 初始state,里面有一个属性items,数组类型,当然可以叫别的名字。

2,aitems的第一个参数state=[],这里为什么会让state赋值一个数组类型呢?不应该是object么?这是 因为在给todos赋值那一句,items:aitems,我对这点的理解是当触发事件的时候,redux会自动遍历todos,然后把state和combineReducers中传入的对象进行比较,遇到同名属性,就把state中的同名属性值传给combineReducers中的同名属性所对应的函数,有点绕!!!!

3,aitems的第二个参数action,你想的没错,就是刚才我们定义的 src/actions/index.js中的方法所   返回的对象。

4,combineReducers函数是一个很有个性的函数,不多说了。

src/index.js:

"use strict";
import React from 'react';
import { render } from 'react-dom';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import  App from './components/App';
import todos from './reducers/index';let store = createStore(todos);let element = document.getElementById('app');
render(<Provider store={store}><App /></Provider>,element
);

这个要说的不太多,因为每个讲react和redux有关的文章里大部分会有这一段,主要是为了把react 和redux 通过 react-redux连接起来。

下面看组件:

src/components/App.js:

"use strict";import React from 'react';
import {connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import  * as actions from '../actions/index';
import AddItem from './AddItem';
import ItemList from './ItemList';class App extends React.Component{render(){console.log("app");return <div><AddItem onAddClick={(text) => this.props.actions.addItem(text)} /><ItemList items={this.props.items} onDelClick={index=>this.props.actions.delItem(index)}/></div>}
}
export default connect(({items})=>({items}),(dispatch) => ({actions:bindActionCreators(actions,dispatch)}))(App);

代码很简单,一看就能明白,唯一复杂一点的就是最后一句:

export default connect(({items})=>({items}),(dispatch) => ({actions:bindActionCreators(actions,dispatch)}))(App);

connect接收两个对象,第一个对象是store中的state,也可以是一部分,会变成绑定view的props属性,第二个对象是actions,也会变成当前view的props属性,这样就可以直接调用同名的actions,会自动派发对应的事件。connect函数执行过后会返回一个函数,再把当前的view传进去,就可以把当前的view,state,action绑定到一起,这样就能在当前的view中使用state的数据和派发事件了。

然后还有两个组件:

src/components/Additem.js:

"use strict";
import React from 'react';export default class AddItem extends React.Component{static propTypes = {onAddClick:React.PropTypes.func};_clickHandle(e){console.log("additemclick");this.props.onAddClick(this.refs.itemText.value.trim());}render(){console.log("additem");return <div><input type="text" ref="itemText"/><br/><button onClick={this._clickHandle.bind(this)}>add</button></div>}
}

这就是普通的react组件了,从父级接收一些参数来使用,或者接收一些函数来实现在子组件中调用父组件的函数。

src/components/ItemList.js:

"use strict";import React from 'react';export default class ItemList extends React.Component{static propTypes={items:React.PropTypes.array.isRequired,onDelClick:React.PropTypes.func};_onDelClick(index){console.log("itemlistclick",index);this.props.onDelClick(index);}render(){console.log("itemlist");console.log(this.props.items);return <ul>{this.props.items.map((value,index) =><li>{index},{value}<button onClick={this._onDelClick.bind(this,index)}>del</button></li>)}</ul>}
}

这个,同上,不再多做解释。

恩。demo到这里,主要代码就完了,再来梳理一遍:

1,src/index.js把所有的包关联起来。

2,定义actions,定义reducers。

3,把state和actions绑定到App.js上。

4,从App.js中把state和actions分别传进子组件。

5,子组件中有操作,就会调用actions.

6,actions被触发,store调用对应的reducers.

7,reducers被调用,修改state.

8,react检测到state被修改,重新渲染组件,改变views。

恩。又跨近了一步。

参考:http://camsong.github.io/redux-in-chinese/docs/basics/ExampleTodoList.html

转载于:https://blog.51cto.com/wuzishu/1750929

node.js学习之react,redux,react-redux相关推荐

  1. node.js学习总结:node.js的内置模块,模块化,npm与包 express,前后端身份认证 JWT认证机制

    node.js学习总结 什么是node.js node.js的内置模块 fs系统模块 path路径模块 http模块 模块化 npm与包 express express路由 express+mysql ...

  2. node.js学习笔记

    # node.js学习笔记标签(空格分隔): node.js---## 一 内置模块学习 ### 1. http 模块 ``` //1 导入http模块 const http =require('ht ...

  3. node.js学习笔记14—微型社交网站

    node.js学习笔记14-微型社交网站 1.功能分析 微博是以用户为中心,因此需要有注册和登录功能. 微博最核心的功能是信息的发表,这个功能包括许多方面,包括:数据库访问,前端显示等. 一个完整的微 ...

  4. Node.js学习笔记8

    Node.js学习笔记8 HTTP服务器与客户端 Node.js的http模块,封装了一个高效的HTTP服务器和一个简易的HTTP客户端 http.server是一个基于事件的HTTP服务器,核心由N ...

  5. node.js学习笔记5——核心模块1

    node.js学习笔记5--核心模块1 Node.js核心模块主要内容包括:(1)全局对象 (2)常用工具 (3)事件机制 (4)文件系统访问 (5)HTTP服务器与客户端 一: 全局对象 Node. ...

  6. 《写给PHP开发者的Node.js学习指南》一2.2 预定义的PHP变量

    本节书摘来自异步社区<写给PHP开发者的Node.js学习指南>一书中的第2章,第2.1节,作者[美]Daniel Howard,更多章节内容可以访问云栖社区"异步社区" ...

  7. node.js 学习笔记(二)模板引擎和C/S渲染

    node.js 学习笔记(二)模板引擎和C/S渲染 文章目录 node.js 学习笔记(二)模板引擎和C/S渲染 一.初步实现Apache功能 1.1 使用模板引擎 1.2 在 node 中使用模板引 ...

  8. Node.js 学习 ——nodemon 运行报错解决

    Node.js 学习 --nodemon 运行报错解决 报错记录 nodemon : 无法加载文件 C:\Users\Administrator.DESKTOP-0RUBNO7\AppDat on.p ...

  9. 千锋Node.js学习笔记

    千锋Node.js学习笔记 文章目录 千锋Node.js学习笔记 写在前面 1. 认识Node.js 2. NVM 3. NPM 4. NRM 5. NPX 6. 模块/包与CommonJS 7. 常 ...

  10. 唤醒手腕 - 前端服务器端开发 Node.Js 学习笔记(学习中,更新中)

    唤醒手腕 - Node.Js 学习笔记 唤醒手腕个人的学习记录,时间在2021年12月13日 ~ 2021年12月14日,学习方式看官方文档和B站视频,如有错误或者代码问题的地方,欢迎C站大佬能够帮忙 ...

最新文章

  1. 预测过去?DeepMind用AI复原古希腊铭文,登Nature封面
  2. 函数式编程之-拒绝空引用异常(Option类型)
  3. c# 的 textbox 默认情况下是有最大字符长度限制的
  4. 可动态调节参数的线程池实现
  5. 5G(1)---5G 协议标准下载
  6. 【Hbase】命令行load数据文件到Hbase
  7. 使用Maven命令安装jar包到repo中
  8. mysql 执行计划不对_mysql tokudb执行计划走的不准确案例
  9. android小米手机变慢,手机越来越慢怎么破?小米手机七大加速绝招
  10. Nemty 勒索软件代码中包含对杀毒软件公司的强烈措辞
  11. OpenBCI_GUI通过lsl传输出来的数据是原始数据吗?
  12. 【ACWing】723. PUM
  13. 阿卡迪亚大学计算机专业好考吗,加拿大阿卡迪亚大学热门专业介绍
  14. 51单片机DIY_秒表计时器
  15. 新颖的基于互联网的毕业设计题目50例
  16. 行业趋势分析 作者:魏小康xiaokang
  17. 国庆七天测(五)马里奥
  18. 初来乍到,请多关照。。。
  19. 每天一个设计模式之模板方法模式(Template Method Pattern)
  20. 这世上没有什么是理所当然的

热门文章

  1. linux二进制数据16进制数据转换,[轉]16进制字符文本/二进制文件迷你互转器
  2. docker镜像和容器的导出导入
  3. java上机实验答案_java上机实验答案与解析
  4. eos节点服务器_长期看,EOS柚子能不能达到1000元?
  5. 开发浏览器监控网页数据变化_贝程学院:Selenium辅助开发工具Firebug和Firepath
  6. cron表达式 每天0点10分和30分_揭开考研阅卷的内幕,注意这些多得20分!
  7. 关于码云的一些基本知识_一些关于 CPU 的基本知识
  8. mac 10.12.6 Fiddler的安装
  9. Vue中子组件如何向父组件传递数据?
  10. 运行报错Error:(29, 41) java: 无法将类 com.imooc.dataobject.ProductCategory中的构造器 ProductCategory应用到给定类型