react:用redux实现简单计算器的过程中使用异步编程的一个小例子

首先是项目的基本结构:
在这里插入图片描述
1、下载redux插件(异步中间件)

npm install --save redux-thunk

2、在redux/store.js中引入

import thunk from 'redux-thunk'

3、在createStore方法中传入一个由applyMiddleware(thunk)返回的函数对象

const store = createStore(calc,composeWithDevTools(applyMiddleware(thunk)))

4、在actions.js中添加异步函数,容器组件app.js中导入该函数,使用react-redux中的connect方法向外暴露连接,使得UI组件calculator.jsx可以接受state和行为函数。

下面即为相关文件代码:
calculator.jsx:

/*
UI组件: 不包含任何redux API
 */
import React,{Component} from "react"
import {PropTypes} from 'prop-types'
import {jia,jian,cheng,chu} from '../redux/actions'

export default class Calculator extends Component {
    static propTypes = {
        state: PropTypes.number.isRequired,
        jia: PropTypes.func.isRequired,
        jian: PropTypes.func.isRequired,
        cheng: PropTypes.func.isRequired,
        chu: PropTypes.func.isRequired,
        empty: PropTypes.func.isRequired,
        handleAsync: PropTypes.func.isRequired,
    }

    handleCal=()=>{
        const {state,jia,jian,cheng,chu} = this.props
        const num1 = this.input1.value.trim()*1
        const num2 = this.input2.value.trim()*1
        if(num1 && num2){
            switch (this.select.value) {
                case 'JIA': jia(num1,num2)
                    break
                case 'JIAN': jian(num1,num2)
                    break
                case 'CHENG': cheng(num1,num2)
                    break
                case 'CHU': chu(num1,num2)
                    break
            }
        }else {
            alert('出错了')
        }

    }
    handleEmp=()=>{
        const {empty} = this.props
        this.input1.value = ''
        this.input2.value = ''
        empty()
    }
    handleAsync=()=>{
        const num1 = this.input1.value.trim()*1
        const num2 = this.input2.value.trim()*1
        if(this.select.value === 'JIA'){
            this.props.handleAsync(num1,num2)
        }
    }
    render () {
        return (
            <div>
                <input type="text" ref={(input1) => this.input1=input1}/>{' '}
                <select ref={(select) => this.select=select}>
                    <option value='JIA'>+</option>
                    <option value='JIAN'>-</option>
                    <option value='CHENG'>*</option>
                    <option value='CHU'>/</option>
                </select>
                {' '}
                <input type="text" ref={(input2) => this.input2=input2}/>{' '}
                ={' '}
                <input type="text" value={this.props.state}/>{' '}
                <button onClick={this.handleCal}>计算</button>
                <button onClick={this.handleEmp}>清空</button>
                <button onClick={this.handleAsync}>async of +</button>
                <br/>
            </div>
        )
    }
}

app.js:

/*
包含Counter组件的容器组件
 */
import React from "react";
import {connect} from 'react-redux'
import Calculator from '../components/calculator'
import {jia,jian,cheng,chu,empty,handleAsync} from '../redux/actions'

export default connect(
    (state) => ({state:state}),
    {jia: jia,jian: jian,cheng: cheng,chu: chu,empty: empty,handleAsync:handleAsync}
)(Calculator)

action-types.js:

/*
包含Counter组件的容器组件
 */
export const JIA = 'jia'
export const JIAN = 'jian'
export const CHENG = 'cheng'
export const CHU = 'chu'
export const EMPTY = 'empty'



actions.js:

import React from "react";
import {JIA,JIAN,CHENG,CHU,EMPTY} from './action-types'

export const jia = (number1,number2) => ({type:JIA,number:[number1,number2]})
export const jian = (number1,number2) => ({type:JIAN,number:[number1,number2]})
export const cheng = (number1,number2) => ({type:CHENG,number:[number1,number2]})
export const chu = (number1,number2) => ({type:CHU,number:[number1,number2]})
export const empty = () => ({type:EMPTY,number:0})

export const handleAsync = (number1,number2) => {
    return dispatch => {
        //模拟ajax请求
        setTimeout( () => {
            //执行异步代码
            dispatch(jia(number1,number2))
        },3000)
    }
}


reducers.js:

import React from "react";

import {JIA, JIAN, CHENG, CHU, EMPTY} from './action-types'

export default function calc(state=0,action) {
    switch (action.type) {
        case JIA: return state = action.number[0] + action.number[1]
        case JIAN: return state = action.number[0] - action.number[1]
        case CHENG: return state = action.number[0] * action.number[1]
        case CHU: return state = action.number[0] / action.number[1]
        case EMPTY: return state = action.number
        default: return state
    }

}

store.js

import React from "react";
import {Createstore} from 'react-redux'
import {createStore,applyMiddleware} from 'redux'
import thunk from 'redux-thunk'
import {composeWithDevTools} from 'redux-devtools-extension'

import calc from './reducers'

//创建store对象
const store = createStore(calc,composeWithDevTools(applyMiddleware(thunk)))
export default store

index.js

import React from "react"
import ReactDOM from 'react-dom'

import App from "./containers/app";
import {Provider} from 'react-redux'
import store from './redux/store'

ReactDOM.render(<Provider store={store}>
    <App/>
</Provider>,document.getElementById('root'))

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
    <title>React App</title>
    <link type="text/css" rel="stylesheet" href="/css/bootstrap.css">
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
  </body>
</html>

大致界面是这样的,有兴趣可以操作下,本人水平有限,有错望指正。只实现了异步的加法,其他类推。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值