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 操作select相关方法函数
Dec 06 Javascript
网页整体变灰白色(兼容各浏览器)实例
Apr 21 Javascript
使用jquery自定义鼠标样式满足个性需求
Nov 05 Javascript
jquery将一个表单序列化为一个对象的方法
Dec 02 Javascript
JavaScript中Number.MAX_VALUE属性的使用方法
Jun 04 Javascript
JS验证图片格式和大小并预览的简单实例
Oct 11 Javascript
详解vue服务端渲染(SSR)初探
Jun 19 Javascript
JS中利用swiper实现3d翻转幻灯片实例代码
Aug 25 Javascript
ejsExcel模板在Vue.js项目中的实际运用
Jan 27 Javascript
微信小程序云开发如何使用npm安装依赖
May 18 Javascript
js实现简单放大镜效果
Mar 07 Javascript
nuxt 服务器渲染动态设置 title和seo关键字的操作
Nov 05 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截取字符串并保留完整xml标签的函数代码
2013/02/06 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(十四)
2014/06/26 PHP
php操作xml入门之xml标签的属性分析
2015/01/23 PHP
php生成图片验证码的方法
2016/04/15 PHP
php实现与python进行socket通信的方法示例
2017/08/30 PHP
in.js 一个轻量级的JavaScript颗粒化模块加载和依赖关系管理解决方案
2011/07/26 Javascript
nodejs的require模块(文件模块/核心模块)及路径介绍
2013/01/14 NodeJs
JS Replace()的高级使用方法介绍
2013/06/29 Javascript
javascript同步服务器时间和同步倒计时小技巧
2015/09/24 Javascript
jquery对dom节点的操作【推荐】
2016/04/15 Javascript
微信小程序 教程之wxapp视图容器 scroll-view
2016/10/19 Javascript
Node.js数据库操作之查询MySQL数据库(二)
2017/03/04 Javascript
将 vue 生成的 js 上传到七牛的实例
2017/07/28 Javascript
AngularJS ionic手势事件的使用总结
2017/08/09 Javascript
vue使用mint-ui实现下拉刷新和无限滚动的示例代码
2017/11/06 Javascript
微信小程序基于slider组件动态修改标签透明度的方法示例
2017/12/04 Javascript
jQuery实现监听下拉框选中内容发生改变操作示例
2018/07/13 jQuery
浅谈vue中组件绑定事件时是否加.native
2019/11/09 Javascript
JS实现百度搜索框
2021/02/25 Javascript
[06:45]2018DOTA2亚洲邀请赛 4.5 SOLO赛 Sccc vs Maybe
2018/04/06 DOTA
Python多线程学习资料
2012/12/19 Python
给Python入门者的一些编程建议
2015/06/15 Python
Python 迭代器工具包【推荐】
2016/05/06 Python
Python2和Python3的共存和切换使用
2019/04/12 Python
Python opencv实现人眼/人脸识别以及实时打码处理
2019/04/29 Python
Python二次规划和线性规划使用实例
2019/12/09 Python
香港永安旅游网:Wing On Travel
2017/04/10 全球购物
澳大利亚领先的在线葡萄酒零售商:Get Wines Direct
2018/03/27 全球购物
.net软件工程师面试题
2015/03/31 面试题
百度JavaScript笔试题
2015/01/15 面试题
应届大学生自荐信格式
2013/09/21 职场文书
初中三年学生的学习自我评价
2013/11/13 职场文书
诚信承诺书范文
2014/03/27 职场文书
同学联谊会邀请函
2019/06/24 职场文书
React 高阶组件HOC用法归纳
2021/06/13 Javascript
Elasticsearch 基本查询和组合查询
2022/04/19 Python