Redux实现组合计数器的示例代码


Posted in Javascript onJuly 04, 2018

Redux是一种解决数据共享的方案

Redux实现组合计数器的示例代码

import {createStore} from 'redux';
import React from 'react';
import ReactDOM from 'react-dom';
import {connect, createProvider} from 'react-redux'


// data
let allNum = {num :1000}

// 创建reducer, 名字的默认值为
function reducer(state, action) {
  let tmp = {}
  if (action.type == "decrease"){
    allNum.num = allNum.num - action.value;
    tmp = Object.assign({}, state, {num: allNum.num})
    return tmp
  }else if(action.type == "increase"){
    allNum.num = allNum.num + action.value;
    tmp = Object.assign({}, state, {num: allNum.num})
    return tmp
  }else{
    return state
  }
}

// 创建store存储数据(传入处理函数reducer, 核心数据allNum)
let store = createStore(reducer, allNum)
console.log("初始化的数据为",store.getState('num'))

// 添加监听函数
store.subscribe(() => {console.log("监听函数发出:", store.getState())});

// 发出action
let tmp = {};
tmp = store.dispatch({type: "decrease", value: 10})
console.log("---->", tmp);
tmp = store.dispatch({type: "decrease", value: 100})
console.log("---->", tmp);
tmp = store.dispatch({type: "increase", value: 31})
console.log("---->", tmp);
tmp = store.dispatch({type: "increase", value: 123})
console.log("---->", tmp);

class MyComponent extends React.Component {
 render() {return <div>Hello World</div>;}
}

ReactDOM.render(<MyComponent />, document.getElementById("root"));

React和Redux组合使用

React组件, 有两个数据集, props和state

props表示外部传入组件的参数(数据由外部传入, 可以被外部更改)

state表示组件固有的属性(数据私有, 不可以被外部更改)

我们可以把多个React组件的props交由Redux进行管理, 这样就实现了React组件之间数据的共享

Redux实现组合计数器的示例代码

组件如何读写数据

组件通过action发送信号, reducer处理action, story内的值被reducer修改, 由于React组件已经被绑定到story中, 所以story内的数据被修改后, 可以直接同步到React的组件中

Redux实现组合计数器的示例代码

小案例: 实现一个组合计数器

单个计数器的数据由组件自身state管理

三个计数器的数据只和由Redux管理

Redux实现组合计数器的示例代码

动图演示

实现的源码如下

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>react-webpack-demo</title>
</head>
<body>
  <div id="root"></div>
</body>
</html>

index.js

import 'babel-polyfill';
import React from 'react';
import ReactDOM from 'react-dom';
import './index.scss';
import Redux from 'redux';
import { connect, Provider } from 'react-redux';
import { createStore } from 'redux';
import { PropTypes } from 'prop-types';

class ManageCounter extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    return ( <div>
      <p className="title">计数器</p> 
      <Counter id = "0" />
      <Counter id = "1" />
      <Counter id = "2" />
      <p className="result"> 组件值的和为: { this.props.sum } </p> 
      </div> )
  }
}


class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.changeSum = this.changeSum.bind(this)
    this.decrease = this.decrease.bind(this)
    this.increase = this.increase.bind(this)
    this.state = { value: 0 };
  }
  changeSum() {
    this.props.dispatch({ type: 'changeSum', payload: { id: this.props.id, value: this.state.value } })
  }
  decrease() {
    let self = this;
    this.setState({ value: this.state.value - 1 }, () => {
      self.changeSum()

    })
  }

  increase() {
    let self = this;
    self.setState({ value: this.state.value + 1 }, () => {
      self.changeSum()
    })
  }

  render() {
    const { value } = this.state;
    let { id } = this.props;
    return ( <div >
      <input type = "button"value = "减1" onClick = { this.decrease }/> 
      <span > { value } < /span><br/ >
      <input type = "button" value = "加1" onClick = { this.increase }/>
      </div> )
  }
}

// 创建reducer
function reducer(state = { number: [0, 0, 0], sum: 0 }, action = {}) {
  if (action.type == 'changeSum') {
    let { id, value } = action.payload
    console.log("id:", id, "value:", value);
    state.number[id] = value
    let tmpSum = 0;
    for (let i = 0; i < state.number.length; i++) {
      tmpSum += state.number[i]
    }
    return Object.assign({}, state, { sum: tmpSum });
  } else {
    return state;
  }
}

const CounterMapStateToProps = (state) => ({

})

const ManageCounterMapStateToProps = (state) => ({
  sum: state.sum
})

const mapDispatchToProps = (dispatch) => ({
  dispatch: dispatch
})


// 创建store
let store = createStore(reducer)
// connect连接
Counter = connect(CounterMapStateToProps, mapDispatchToProps)(Counter)
ManageCounter = connect(ManageCounterMapStateToProps, mapDispatchToProps)(ManageCounter)

ReactDOM.render(
  <Provider store = { store }>
  <ManageCounter />
  </Provider> ,
  document.getElementById('root'));

index.scss

$designWidth: 750;
@function px2rem($px) {
  @return $px*10/$designWidth+rem;
}

#root {
  div {
    p {
      font-size: px2rem(300);
      color: #5EA1F3;
      text-align: center;
    }
    div {
      font-size: px2rem(500);
      display: flex;
      color: #64B587;
      border: 1px solid #F0BB40;
      input {
        flex: 1 1 auto;
        background-color: #64B587;
        font-size: px2rem(200);
        outline: none;
        color:#ffffff;
      }
      span {
        width: 300px;
        flex: 1 1 auto;
        text-align: center;
      }
    }
    .title {
      color: #BDBDBD;
    }
    .result {

      font-size: px2rem(200);
    }
  }
}

小结

redux的设计思想是很简单的, 也有了很成熟的库函数供我们调用, 所以面对一个问题时, 我们考虑的重点是: React组件内哪些数据需要被Redux管理?把重点问题考虑清楚, 问题也就解决了大半!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
利用onresize使得div可以随着屏幕大小而自适应的代码
Jan 15 Javascript
jquery animate图片模向滑动示例代码
Jan 26 Javascript
js过滤特殊字符输入适合输入、粘贴、拖拽多种情况
Mar 22 Javascript
jQuery插件jPaginate实现无刷新分页
May 04 Javascript
AJAX实现瀑布流触发分页与分页触发瀑布流的方法
May 23 Javascript
jquery+ajax实现直接提交表单实例分析
Jun 17 Javascript
JavaScript 网页中实现一个计算当年还剩多少时间的倒数计时程序
Jan 25 Javascript
微信小程序 开发经验整理
Feb 15 Javascript
php输出全部gb2312编码内的汉字方法
Mar 04 Javascript
微信小程序 图片宽高自适应详解
May 11 Javascript
Bootstrap table表格初始化表格数据的方法
Jul 25 Javascript
vue组件三大核心概念图文详解
May 30 Javascript
用Node编写RESTful API接口的示例代码
Jul 04 #Javascript
微信小程序踩坑记录之解决tabBar.list[3].selectedIconPath大小超过40kb
Jul 04 #Javascript
JS实现点击按钮可实现编辑功能
Jul 03 #Javascript
详解vue-cli中模拟数据的两种方法
Jul 03 #Javascript
echarts同一页面中四个图表切换的js数据交互方法示例
Jul 03 #Javascript
基于React+Redux的SSR实现方法
Jul 03 #Javascript
VUE 3D轮播图封装实现方法
Jul 03 #Javascript
You might like
PHP根据IP地址获取所在城市具体实现
2013/11/27 PHP
PHP实现加强版加密解密类实例
2015/07/29 PHP
用javascript实现分割提取页面所需内容
2007/05/09 Javascript
Firefox window.close()的使用注意事项
2009/04/11 Javascript
javascript 数组排序函数
2009/08/20 Javascript
jQuery EasyUI API 中文文档 - EasyLoader 加载器
2011/09/29 Javascript
JavaScript中两个感叹号的作用说明
2011/12/28 Javascript
含有CKEditor的表单如何提交
2014/01/09 Javascript
JS替换文本域内的回车示例
2014/02/18 Javascript
js实现的类似于asp数据字典的数据类型代码实例
2014/09/03 Javascript
网页中表单按回车就自动提交的问题的解决方案
2014/11/03 Javascript
javascript实现二级级联菜单的简单制作
2015/11/19 Javascript
理解js回收机制通俗易懂版
2016/02/29 Javascript
JS实现图片平面旋转的方法
2016/03/01 Javascript
jquery.tableSort.js表格排序插件使用方法详解
2020/08/12 Javascript
vue使用watch 观察路由变化,重新获取内容
2017/03/08 Javascript
微信小程序page的生命周期和音频播放及监听实例详解
2017/04/07 Javascript
Node.js中,在cmd界面,进入退出Node.js运行环境的方法
2018/05/12 Javascript
基于node搭建服务器,写接口,调接口,跨域的实例
2018/05/13 Javascript
[40:57]TI4 循环赛第二日 iG vs EG
2014/07/11 DOTA
[01:15:00]LGD vs Mineski Supermajor 胜者组 BO3 第一场 6.5
2018/06/06 DOTA
基于Python_脚本CGI、特点、应用、开发环境(详解)
2017/05/23 Python
详解Python核心编程中的浅拷贝与深拷贝
2018/01/07 Python
Python Matplotlib实现三维数据的散点图绘制
2019/03/19 Python
opencv3/C++ 平面对象识别&amp;透视变换方式
2019/12/11 Python
Python基于read(size)方法读取超大文件
2020/03/12 Python
matplotlib图例legend语法及设置的方法
2020/07/28 Python
Python2与Python3关于字符串编码处理的差别总结
2020/09/07 Python
Python接口自动化系列之unittest结合ddt的使用教程详解
2021/02/23 Python
任意存:BOXFUL
2018/05/21 全球购物
如何写出高性能的JSP和Servlet
2013/01/22 面试题
实习报告评语
2014/04/26 职场文书
淘宝活动总结范文
2014/06/26 职场文书
班级团队活动方案
2014/08/14 职场文书
2014党员整改措施思想汇报
2014/10/07 职场文书
使用react-virtualized实现图片动态高度长列表的问题
2021/05/28 Javascript