Redux初探

通过一个官方例子Counter来入门redux

前置知识
参考:Redux入门

注意:大致看完参考资料后,clone下面代码,然后运行下,理解其执行流程,遇到不明白的就console.log,查看官方文档

功能实现

  • 当按 “+”时,数字加1
  • 当按 “-”时,数字减1

先上代码:
index.js

import React from 'react'
import ReactDOM from 'react-dom'
import { createStore } from 'redux'
import Counter from './components/Counter'
import counter from './reducers'

// counter ==== reducer
const store = createStore(counter)
const rootEl = document.getElementById('root')

const render = () => ReactDOM.render(
  <Counter
    value={store.getState()}
    // 当点击时分发一个action,然后store会自动调用reducer,
    // 并传入两个参数:当前的state和action,action决定了要执行哪个行为,
    // reducer执行完成后,返回一个新的state
    // 该action会被store的reducer
    onIncrement={() => store.dispatch({ type: 'INCREMENT' })}
    onDecrement={() => store.dispatch({ type: 'DECREMENT' })}
  />,
  rootEl
)

function clicked() {
  console.log('clicked');
}

render()
// 设置store的监听函数为render,state的每次改变,都会去执行subscribe;
// 注意:这里说的执行subscribe,简单的理解就是当state的改变时,去查询
// 使用store.subscribe注册了哪些函数,然后去执行它们,例如下面我使用subscribe注册了
// render和clicked,那么当state改变时就去执行这两个函数
store.subscribe(render);

reducer.js

export default (state = 10, action) => {

  switch (action.type) {
    case 'INCREMENT':
      return state + 1
    case 'DECREMENT':
      return state - 1
    default:
      return state
  }
}

Counter.js

import React, { Component } from 'react'
import PropTypes from 'prop-types'

class Counter extends Component {
  constructor(props) {
    super(props);
    this.incrementAsync = this.incrementAsync.bind(this);
    this.incrementIfOdd = this.incrementIfOdd.bind(this);
  }

  incrementIfOdd() {
    if (this.props.value % 2 !== 0) {
      this.props.onIncrement()
    }
  }

  incrementAsync() {
    setTimeout(this.props.onIncrement, 1000)
  }

  render() {
    const { value, onIncrement, onDecrement } = this.props
    return (
      <p>
        Clicked: {value} times
        {' '}
        <button onClick={onIncrement}>
          +
        </button>
        {' '}
        <button onClick={onDecrement}>
          -
        </button>
        {' '}
        <button onClick={this.incrementIfOdd}>
          Increment if odd
        </button>
        {' '}
        <button onClick={this.incrementAsync}>
          Increment async
        </button>
      </p>
    )
  }
}

Counter.propTypes = {
  value: PropTypes.number.isRequired,
  onIncrement: PropTypes.func.isRequired,
  onDecrement: PropTypes.func.isRequired
}

export default Counter

执行流程如下:

  1. 使用createStore(counter) 去创建了一个store,并传入reducer,
    这里的counter是reducer

  2. 当按下 按钮-加 或 按钮-减 时,说明有事件产生,所以需要对state进行改变;
    在redux中,我们不直接对state进行改变,而是通过dispatch分发actions来处理,
    也就是给dispatch传递一个actions(其实就是一个对象),而actions里面
    有一个默认的属性: type,这个type就可以定义我们当前执行了什么操作;在这个例子中,
    我们就只有两个操作:加 和 减,因此,我们就定义了两种action,分别为:
    { type: 'INCREMENT' } 和 { type: 'DECREMENT' } ,这是第二步;
    注意:actions 只是描述状态发生了改变,但是应用程序接下来怎么操作,不是它关心的,
    这是reducer的事情

  3. 当执行完dispatch之后,也就是我们的actions发送出去之后,我们肯定是需要别人回应,
    不然我们干嘛发送actions,所以,在redux中,当我们执行完dispatch之后,redux会自动去
    执行reducer函数,同时会将当前的state和我们发送的actions传入到reducer函数中,
    reducer函数根据actions中的type属性来决定要“执行怎样的操作”(其实就是返回一个新的
    state),返回的新的state将store中的state更新。
    注意:reducer是一个纯函数,也就是说同样的输入,得到相同的输出,而且没有任何可观察到的
    副作用;所以在reducer中,我们是返回一个新的state,而不是改变当前state,reducer函数的
    设计,参考:http://redux.js.org/docs/basics/Reducers.html

  4. 当执行完reducer之后,state的状态被更新,这时就会执行store.subscibe(listener),
    也就是说一旦state更新,就会执行store.subscribe,注意:这里说的执行store.subscribe,
    其实是执行其中的listener函数,可以这么理解:假设我们使用store.subscribe()注册了很多
    监听函数,如:store.subscibe(listener1),store.subscibe(listener2),
    store.subscibe(listener3),可以假想是将listener1、listener2和listener3放到一个数组中,
    当state改变时,redux会从这个数组中将listener1、listener2和listener3拿出来,依次执行。
    在该函数中,我们监听的是render函数,也就是当state改变时,我们就刷新页面;

  5. 在Counter组件中,传入state作为value值,state的获取是通过store.getState()来实现的,
    通过这几个过程就实现了 加 减 数值的功能;

  6. 总结下流程:a. 首先创建一个store(createStore)
    b. 定义reducer函数,reducer函数决定了我们需要哪些actions
    c. 为不同的操作,定义不同的actions,然后使用store.dispatch(actions)分发
    d. 绑定监听对象,我们这里绑定的是render()函数
    e. 完成
    最最重要的是:实践跑代码,console.log

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,406评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,732评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,711评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,380评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,432评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,301评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,145评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,008评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,443评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,649评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,795评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,501评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,119评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,731评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,865评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,899评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,724评论 2 354

推荐阅读更多精彩内容

  • http://gaearon.github.io/redux/index.html ,文档在 http://rac...
    jacobbubu阅读 79,959评论 35 198
  • 学习必备要点: 首先弄明白,Redux在使用React开发应用时,起到什么作用——状态集中管理 弄清楚Redux是...
    贺贺v5阅读 8,902评论 10 58
  • 看到这篇文章build an image gallery using redux saga,觉得写的不错,长短也适...
    smartphp阅读 6,156评论 1 29
  • 前言 本文 有配套视频,可以酌情观看。 文中内容因各人理解不同,可能会有所偏差,欢迎朋友们联系我讨论。 文中所有内...
    珍此良辰阅读 11,906评论 23 111
  • 七月二十八日,连续多日炙热难耐的高温天气,经过昨天下午一场大雨,温度下降了许多。往日一动就汗流浃背的天气,可是半个...
    高安让阅读 1,800评论 6 7