一个被写烂的redux计数小例子

栏目: 服务器 · 发布时间: 5年前

内容简介:Action 本质上是 JavaScript 普通对象。action 内必须使用一个字符串类型的 type 字段来表示将要执行的动作,但是这样有多少action就需要写多少action,所以这里需要action creator, 这个action构造函数返回一个js对象,当然这里在处理异步数据的时候需要返回一个函数,此时需要用到中间件。reducer具体定义可以看redux自述中的定义,由于demo太简单,拆分合并reducer大家自己看吧,这里主要介绍redux在react中的工作流程。 这里要注意re
  • 通过create-react-app快速搭建react项目
  • 安装依赖npm install redux react-redux redux-thunk --save (redux-thunk是处理异步数据流的中间件)
  • 更改,新建项目目录
一个被写烂的redux计数小例子
  • 效果图
    一个被写烂的redux计数小例子

Demo开始

编写redux相关内容

action

export const Increment = 'increment'
export const Decrement = 'decrement'
/*action creator action构造函数*/
export const increment = (counterIndex) => {
  type:Increment,
  counterIndex
}
export const decrement = (counterIndex) => ({
  type: Decrement,
  counterIndex
})
复制代码

Action 本质上是 JavaScript 普通对象。action 内必须使用一个字符串类型的 type 字段来表示将要执行的动作,但是这样有多少action就需要写多少action,所以这里需要action creator, 这个action构造函数返回一个js对象,当然这里在处理异步数据的时候需要返回一个函数,此时需要用到中间件。

reducer

import { Increment, Decrement } from '../Action'
export default (state,action) => {
  const {counterIndex} = action
  switch (action.type) {
    case Increment:
    return {...state, [counterIndex]:state[counterIndex]+1}
    case Decrement:
    return {...state, [counterIndex]:state[counterIndex]-1}
    default:
    return state
  }
}
复制代码

reducer具体定义可以看redux自述中的定义,由于demo太简单,拆分合并reducer大家自己看吧,这里主要介绍redux在react中的工作流程。 这里要注意reducer是个纯函数,不能更改state,这里返回的新state可以使用Object.assign 以及 es6的对象扩展符。

store

import {applyMiddleware, createStore} from 'redux'
import thunk from 'redux-thunk'
import reducer from '../Reducer'
const initValue={
    'First':1,
    'Second':5,
    'Third':6
}
const store=createStore(reducer,initValue)
export default store
复制代码

createStorestore 可以接受一个初始的state,这里可以设置服务端同构应用的初始化props。 至此redux的相关就结束,下面写ui组件。

编写UI组件

如果不用react-redux自动生成容器组件,组件划分就要有容器组件和展示的区分,我理解的展示组件就是没有自己的state,只接受 props决定UI该如何展示,所有的逻辑都在容器组件进行,由于react-redux,我们不需要自己写容器组件

Counter

import React, { Component } from 'react';
    import {increment, decrement} from '../Redux/Action'
    import {connect} from 'react-redux'
    import '../style/App.css';
    const buttonMargin= {
      margin: "20px"
    }
    
    function Counter({index, Increment, Decrement, value}){
      return (
                <div>
                   <button style={buttonMargin} onClick={Increment}>+</button>
                   <button style={buttonMargin} onClick={Decrement}>-</button>
                   <span>{index} count :{value}</span>
                </div>
      )
    }
    function mapStateToProps(state,ownProps){
      return{
        value:state[ownProps.index]
      }
    }
    function mapDispatchToProps(dispatch, ownProps){
      return{
        Increment:() => {
          dispatch(increment(ownProps.index))
        },
        Decrement:() => {
          dispatch(decrement(ownProps.index))
        }
      }
    }
    
    export default connect(mapStateToProps, mapDispatchToProps)(Counter);
复制代码
  • react-redux提供方法connect()和组件,这里说下connect(),引用阮一峰大神的总结: connect方法接受两个参数:mapStateToProps和mapDispatchToProps。它们定义了 UI 组件的业务逻辑。前者负责输入逻辑,即将state映射到 UI 组件的参数(props),后者负责输出逻辑,即将用户对 UI 组件的操作映射成 Action。
  • mapStateToProps:作为函数,mapStateToProps执行后应该返回一个对象,里面的每一个键值对就是一个映射。 接受两个参数state,ownProps,state 。state更新的时候,就会自动执行,重新计算 UI 组件的参数,从而触发 UI 组件的重新渲染,ownProps代表容器组件的props对象,如果容器组件的参数发生变化,也会引发 UI 组件重新渲染,例如上面个的计数;
  • mapDispatchToProps是connect函数的第二个参数,用来建立 UI 组件的参数到store.dispatch方法的映射。也就是说,它定义了哪些用户的操作应该当作 Action,传给 Store。它可以是一个函数,也可以是一个对象

Panel

import React, { Component } from 'react'
import Counter from './Counter.js'
const style = {
    margin: "20px"
}

class Panel extends Component {
    render() {
        return (
            <div style={style}>
                <Counter index="First" />
                <Counter index="Second"/>
                <Counter index="Third" />
                <hr/>
            </div>
        )
    }
}
复制代码

export default Panel

这里就是个list。

index.js(入口文件)

import React from 'react';
import ReactDOM from 'react-dom';
import './style/index.css';
import Panel from './Component/Panel';
import {Provider} from 'react-redux';
import store from './Redux/Store/store.js'
import registerServiceWorker from './registerServiceWorker';

ReactDOM.render(
       <Provider store={store}>
         <Panel/>
       </Provider>,<pre>
   document.getElementById('root')
  );
registerServiceWorker();
复制代码

React-Redux 提供Provider组件,可以让容器组件拿到state,避免一层层向下传,原理是context,其实也很好理解,vue有个bus。 至此一个同步的redux处理数据的demo就完成了,下面来说异步。

异步

vuex 提交的是Mutation(有点像git) 这个东西是同步, 而它有action 这里可以同步异步,但redux并没有,所以这里就有了中间件的出现,用于解决异步action,中间件有几种常用的,这里只简单写下redux-thunk。 action creator 原则是返回一个js对象,异步在这里处理,返回的是一个函数,这就需要中间件的处理。 修改这两处:

action:

export const Increment = 'increment'
export const Decrement = 'decrement'

export const increment = (counterIndex) => {
   return dispatch => {
		let asyncAct = {
			type:Increment,
                        counterIndex
		}
		setTimeout(()=>{ //两秒钟之后再发送action
			dispatch(asyncAct);
		}, 2000)
	}
 }
export const decrement = (counterIndex) => ({
   type: Decrement,
   counterIndex
 })
复制代码

store:

import {applyMiddleware, createStore} from 'redux'
import thunk from 'redux-thunk'
import reducer from '../Reducer'
const initValue={
    'First':1,
    'Second':5,
    'Third':6
}
const store=createStore(reducer,initValue,applyMiddleware(thunk))
//使用中间件的写法applyMiddleware,如果多个,注意里面中间件的顺序
export default store
复制代码

简单的延时2s再计数完成啦。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Just My Type

Just My Type

Simon Garfield / Profile Books / 2010-10-21 / GBP 14.99

What's your type? Suddenly everyone's obsessed with fonts. Whether you're enraged by Ikea's Verdanagate, want to know what the Beach Boys have in common with easy Jet or why it's okay to like Comic Sa......一起来看看 《Just My Type》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

URL 编码/解码
URL 编码/解码

URL 编码/解码

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具