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 相关文章推荐
js清空form表单中的内容示例
May 20 Javascript
深入分析JSONP跨域的原理
Dec 10 Javascript
jquery使用正则表达式验证email地址的方法
Jan 22 Javascript
ANGULARJS中使用JQUERY分页控件
Sep 16 Javascript
jQuery实现验证年龄简单思路
Feb 24 Javascript
AngularJS 作用域详解及示例代码
Aug 17 Javascript
Bootstrap基本组件学习笔记之列表组(11)
Dec 07 Javascript
jQuery中select与datalist制作下拉菜单时的区别浅析
Dec 30 Javascript
Web 开发中Ajax的Session 超时处理方法
Jan 19 Javascript
JavaScript实现短暂提示框功能
Apr 04 Javascript
angular使用md5,CryptoJS des加密的方法
Jun 03 Javascript
微信小程序跳转到其他网页(外部链接)的实现方法
Sep 20 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
星际争霸中的热键
2020/03/04 星际争霸
PHP+JS无限级可伸缩菜单详解(简单易懂)
2007/01/02 PHP
php上传文件的增强函数
2010/07/21 PHP
《PHP编程最快明白》第四讲:日期、表单接收、session、cookie
2010/11/01 PHP
PHP基于单例模式编写PDO类的方法
2016/09/13 PHP
PHP实现的redis主从数据库状态检测功能示例
2017/07/20 PHP
浅谈laravel中的关联查询with的问题
2019/10/10 PHP
return false;和e.preventDefault();的区别
2010/07/11 Javascript
jquery利用event.which方法获取键盘输入值的代码
2011/10/09 Javascript
为原生js Array增加each方法
2012/04/07 Javascript
innerHTML动态添加html代码和脚本兼容多个浏览器
2014/10/11 Javascript
JavaScript基础教程之alert弹出提示框实例
2014/10/16 Javascript
js代码延迟一定时间后执行一个函数的实例
2017/02/15 Javascript
原生js实现简单的Ripple按钮实例代码
2017/03/24 Javascript
利用Decorator如何控制Koa路由详解
2018/06/26 Javascript
Node.js安装详细步骤教程(Windows版)详解
2019/09/01 Javascript
node使用mysql获取数据库数据中文乱码问题的解决
2019/12/02 Javascript
用vue 实现手机触屏滑动功能
2020/05/28 Javascript
深入了解JS之作用域和闭包
2020/06/16 Javascript
vue cli3.0打包上线静态资源找不到路径的解决操作
2020/08/03 Javascript
[09:13]2014DOTA2国际邀请赛 中国区预选赛coser表演
2014/05/23 DOTA
[54:47]Liquid vs VP Supermajor决赛 BO 第五场 6.10
2018/07/05 DOTA
[01:00:14]DOTA2官方TI8总决赛纪录片 真视界True Sight
2019/01/16 DOTA
python创建只读属性对象的方法(ReadOnlyObject)
2013/02/10 Python
Python2与python3中 for 循环语句基础与实例分析
2017/11/20 Python
关于python列表增加元素的三种操作方法
2018/08/22 Python
CentOS下Python3的安装及创建虚拟环境的方法
2018/11/28 Python
Python 普通最小二乘法(OLS)进行多项式拟合的方法
2018/12/29 Python
Python中logging实例讲解
2019/01/17 Python
学python爬虫能做什么
2020/07/29 Python
15款Python编辑器的优缺点,别再问我“选什么编辑器”啦
2020/10/19 Python
NFL墨西哥官方商店:Tienda NFL
2017/11/28 全球购物
WINDOWS域的具体实现方式是什么
2014/02/20 面试题
国际经济与贸易专业求职信
2014/07/10 职场文书
2015年国庆节新闻稿
2015/07/18 职场文书
用position:sticky完美解决小程序吸顶问题的实现方法
2021/04/24 HTML / CSS