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 相关文章推荐
asp javascript 实现关闭窗口时保存数据的办法
Nov 24 Javascript
PNG背景在不同浏览器下的应用
Jun 22 Javascript
JQuery中使用Ajax赋值给全局变量失败异常的解决方法
Aug 18 Javascript
浅谈JavaScript字符串拼接
Jun 25 Javascript
jquery弹出框插件jquery.ui.dialog用法分析
Aug 20 Javascript
jQuery使用siblings获取某元素所有同辈(兄弟姐妹)元素用法示例
Jan 30 Javascript
vue多种弹框的弹出形式的示例代码
Sep 18 Javascript
JS实现的简单下拉框联动功能示例
May 11 Javascript
vue两个组件间值的传递或修改方式
Jul 04 Javascript
JavaScript事件对象深入详解
Dec 30 Javascript
JS实现关闭小广告特效
Jan 29 Javascript
vue利用全局导航守卫作登录后跳转到未登录前指定页面的实例代码
May 19 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如何将log信息写入服务器中的log文件
2015/07/29 PHP
CodeIgniter表单验证方法实例详解
2016/03/03 PHP
JS中不为人知的五种声明Number的方式简要概述
2013/02/22 Javascript
js实现动态改变字体大小代码
2014/01/02 Javascript
JS的参数传递示例介绍
2014/02/08 Javascript
JavaScript运行时库属性一览表
2014/03/14 Javascript
基于JS判断iframe是否加载成功的方法(多种浏览器)
2016/05/13 Javascript
jQuery ajax应用总结
2016/06/02 Javascript
jQuery EasyUI常用数据验证汇总
2016/09/18 Javascript
jQuery EasyUI 页面加载等待及页面等待层
2017/02/06 Javascript
NodeJS简单实现WebSocket功能示例
2018/02/10 NodeJs
深入理解JavaScript 中的执行上下文和执行栈
2018/10/23 Javascript
Vue中实现权限控制的方法示例
2019/06/07 Javascript
在vue项目中使用codemirror插件实现代码编辑器功能
2019/08/27 Javascript
vue-以文件流-blob-的形式-下载-导出文件操作
2020/08/07 Javascript
解决vue初始化项目一直停在downloading template的问题
2020/11/09 Javascript
wxPython 入门教程
2008/10/07 Python
Python3.x和Python2.x的区别介绍
2013/02/12 Python
在Linux下调试Python代码的各种方法
2015/04/17 Python
Python函数可变参数定义及其参数传递方式实例详解
2015/05/25 Python
Python基于分水岭算法解决走迷宫游戏示例
2017/09/26 Python
Python基础教程之异常详解
2019/01/10 Python
Python常见读写文件操作实例总结【文本、json、csv、pdf等】
2019/04/15 Python
Django给admin添加Action的步骤详解
2019/05/01 Python
face++与python实现人脸识别签到(考勤)功能
2019/08/28 Python
OpenCV+python实现膨胀和腐蚀的示例
2020/12/21 Python
Android本地应用打开方法——通过html5写连接
2016/03/11 HTML / CSS
阿玛瑞酒店中文官方网站:Amari.com
2018/02/13 全球购物
英国国家美术馆商店:National Gallery
2019/05/01 全球购物
Python面试题:Python是如何进行内存管理的
2014/08/04 面试题
家具促销活动方案
2014/02/16 职场文书
金融管理专业毕业生求职信
2014/03/12 职场文书
授权委托书范本
2014/04/03 职场文书
25句企业管理语录:助你迅速打开思路,句句经典!
2020/01/14 职场文书
详解Laravel制作API接口
2021/05/31 PHP
Springboot如何同时装配两个相同类型数据库
2021/11/17 Java/Android