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 相关文章推荐
jQuery版Tab标签切换
Mar 16 Javascript
正负小数点后两位浮点数实现原理及代码
Sep 06 Javascript
js利用事件的阻止冒泡实现点击空白模态框的隐藏
Jan 24 Javascript
node.js实现逐行读取文件内容的代码
Jun 27 Javascript
Javascript中arguments用法实例分析
Jun 13 Javascript
jQuery使用zTree插件实现树形菜单和异步加载
Feb 25 Javascript
再谈Javascript中的基本类型和引用类型(推荐)
Jul 01 Javascript
JS数组返回去重后数据的方法解析
Jan 03 Javascript
Vuex之理解Mutations的用法实例
Apr 19 Javascript
JavaScript的继承实现小结
May 07 Javascript
Vue.js组件实现选项卡以及切换特效
Jul 24 Javascript
jQuery表单校验插件validator使用方法详解
Feb 18 jQuery
用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配置心得包含MYSQL5乱码解决
2006/11/20 PHP
php中call_user_func函数使用注意事项
2014/11/21 PHP
PHP如何读取由JavaScript设置的Cookie
2017/03/22 PHP
Joomla框架实现字符串截取的方法示例
2017/07/18 PHP
phpmyadmin在宝塔面板里进不去的解决方案
2020/07/06 PHP
Gambit vs CL BO3 第二场 2.13
2021/03/10 DOTA
Javascript UrlDecode函数代码
2010/01/09 Javascript
分享10篇优秀的jQuery幻灯片制作教程及应用案例
2011/04/16 Javascript
jQuery插件实现表格隔行换色且感应鼠标高亮行变色
2013/09/22 Javascript
JavaScript 数组详解
2013/10/10 Javascript
IE6下拉框图层问题探讨及解决
2014/01/03 Javascript
js的延迟执行问题分析
2014/06/23 Javascript
jQuery焦点控制图层展示延迟隐藏的方法
2015/03/09 Javascript
微信小程序 开发指南详解
2016/09/27 Javascript
使用jQuery操作DOM的方法小结
2017/02/27 Javascript
vue一个页面实现音乐播放器的示例
2018/02/06 Javascript
JavaScript中的&quot;=、==、===&quot;区别讲解
2019/01/22 Javascript
Vue.js路由实现选项卡简单实例
2019/07/24 Javascript
jQuery实现鼠标放置名字上显示详细内容气泡提示框效果的方法分析
2020/04/04 jQuery
详解vue父子组件状态同步的最佳方式
2020/09/10 Javascript
关于Js中new操作符的作用详解
2021/02/21 Javascript
Python学习笔记(二)基础语法
2014/06/06 Python
Python爬取Coursera课程资源的详细过程
2014/11/04 Python
Python中分数的相关使用教程
2015/03/30 Python
python正则表达式的使用
2017/06/12 Python
符合语言习惯的 Python 优雅编程技巧【推荐】
2018/09/25 Python
Python数据可视化:泊松分布详解
2019/12/07 Python
是什么让J2EE适合用来开发多层的分布式的应用
2015/01/16 面试题
小小的船教学反思
2014/02/21 职场文书
法定代表人授权委托书范文
2014/08/02 职场文书
常务副县长“三严三实”对照检查材料思想汇报
2014/10/05 职场文书
个人诉讼委托书范本
2014/10/17 职场文书
解除施工合同协议书
2014/10/17 职场文书
工作保证书怎么写
2015/02/28 职场文书
餐厅服务员管理制度
2015/08/05 职场文书
HTML中的表单Form实现居中效果
2021/05/25 HTML / CSS