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 相关文章推荐
event.X和event.clientX的区别分析
Oct 06 Javascript
jQuery判断当前点击的是第几个li的代码
Sep 26 Javascript
js实现缓冲运动效果的方法
Apr 10 Javascript
js实现页面跳转的五种方法推荐
Mar 10 Javascript
JS给Array添加是否包含字符串的简单方法
Oct 29 Javascript
基于Three.js插件制作360度全景图
Nov 29 Javascript
浅析javascript中的Event事件
Dec 09 Javascript
JavaScript 事件流、事件处理程序及事件对象总结
Apr 01 Javascript
vue 实现 ios 原生picker 效果及实现思路解析
Dec 06 Javascript
使用live-server快速搭建本地服务器+自动刷新的方法
Mar 09 Javascript
vue-cli构建项目下使用微信分享功能
May 28 Javascript
element中Steps步骤条和Tabs标签页关联的解决
Dec 08 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
与空气斗智斗勇的经典《Overlord》,传说中的“无稽之谈”
2020/04/09 日漫
thinkPHP中分页用法实例分析
2015/12/26 PHP
解决 FireFox 下[使用event很麻烦] 的问题.
2006/08/22 Javascript
jQuery 改变CSS样式基础代码
2010/02/11 Javascript
JQuery 绑定select标签的onchange事件,弹出选择的值,并实现跳转、传参
2011/01/06 Javascript
img onload事件绑定各浏览器均可执行
2012/12/19 Javascript
jQuery中对节点进行操作的相关介绍
2013/04/16 Javascript
javascript模拟实现ajax加载框实例
2014/10/15 Javascript
jQuery简单实现网页选项卡特效
2014/11/24 Javascript
学习javascript的闭包,原型,和匿名函数之旅
2015/10/18 Javascript
使用jQuery制作Web页面遮罩层插件的实例教程
2016/05/26 Javascript
AngularJs 动态加载模块和依赖
2016/09/15 Javascript
微信小程序 特效菜单抽屉效果实例代码
2017/01/11 Javascript
ionic3+Angular4实现接口请求及本地json文件读取示例
2017/10/11 Javascript
vue.js简单配置axios的方法详解
2017/12/13 Javascript
vue 自定义指令自动获取文本框焦点的方法
2018/08/25 Javascript
jQuery实现数字自动增加或者减少的动画效果示例
2018/12/11 jQuery
产制造追溯系统之通过微信小程序实现移动端报表平台
2019/06/03 Javascript
Node.js爬虫如何获取天气和每日问候详解
2019/08/26 Javascript
构建Vue大型应用的10个最佳实践(小结)
2019/11/07 Javascript
ES2020 新特性(种草)
2020/01/12 Javascript
kNN算法python实现和简单数字识别的方法
2014/11/18 Python
python中的随机函数小结
2018/01/27 Python
python输出100以内的质数与合数实例代码
2018/07/08 Python
Python 十六进制整数与ASCii编码字符串相互转换方法
2018/07/09 Python
Python实现进度条和时间预估的示例代码
2020/06/02 Python
Spring @Enable模块驱动原理及使用实例
2020/06/23 Python
Python requests HTTP验证登录实现流程
2020/11/05 Python
String s = new String(“xyz”);创建了几个String Object?
2015/08/05 面试题
小学趣味运动会加油稿
2014/09/25 职场文书
大学生国家助学金感谢信
2015/01/23 职场文书
房屋租赁意向书范本
2015/05/09 职场文书
工伤调解协议书
2016/03/21 职场文书
python函数指定默认值的实例讲解
2021/03/29 Python
世界十大动漫制作公司排行榜,迪士尼上榜,第二是美国代表性文化符
2022/03/18 欧美动漫
速龙x4-860k处理器相当于i几
2022/04/20 数码科技