使用
redux-thunk
applyMiddleware
一般流程 在 dispatch 後會將 action 的內容傳給 reducer
在非同步的動作下 會將一般流程的部分 放在 非同步的 callback 下 非同步執行完後 接著執行
以下是我個人的寫法
actions
將兩個 action 包裝成 async 的 function
const setNum = setNum =>({ type:"SETNUM" , num:setNum }) const asyncAdd = function(){ return async function(dispatch , state){ var n = await asyncadd(); return n; } } const asyncMinus = function(){ return async function(dispatch , state){ var n = await asyncminus(); return n; } } async function asyncadd() { return new Promise(function(resolve , reject){ setTimeout(function(){ resolve(1); } , 500) }) } async function asyncminus() { return new Promise(function(resolve , reject){ setTimeout(function(){ resolve(-1); } , 500) }) } export {setNum , asyncAdd , asyncMinus}
reducer
reducer 無法執行 非同步動作
基本上就是負責 非同步結束後 state 的變化
const reducer = (state={'value':0}, action) => { switch (action.type) { case 'SETNUM': return {'value':state['value']+action.num}; default: return {'value':state['value']}; } } export default reducer
container
再傳給 component 的 function 中 將 非同步動作進行 return
import React from 'react'; import Counter from '../component/Counter'; import {setNum , asyncAdd , asyncMinus} from '../actions/action' import { connect } from 'react-redux'; const mapStateToProps = state =>({value:state}); const mapDispatchToProps = (dispatch , props) => ({ onAsyncIncrement:function(){ return dispatch(asyncAdd())} , onAsyncDecrement:function(){return dispatch(asyncMinus())}, setNum:function(num){dispatch(setNum(num))} } ); export default connect(mapStateToProps ,mapDispatchToProps )(Counter);
component
將 container 傳的 function 在這邊進行包裝 將從 action 裡面回傳的 promise 寫入 resolve
import React from 'react';
export default class Counter extends React.Component
{
  constructor(props) {
    super(props);
  }
  asyncIncrement()
  {
    this.props.onAsyncIncrement().then(function(num){
        this.props.setNum(num);
    }.bind(this))
  }
  asyncDecrement()
  {
      this.props.onAsyncDecrement().then(function(num){
        this.props.setNum(num);
    }.bind(this))
  }
  render() {
    return(
            <p>
                Clicked: {this.props.value.value} times
                <button onClick={this.asyncIncrement.bind(this)}>
                    async +
                </button>
                <button onClick={this.asyncDecrement.bind(this)}>
                    async -
                </button>
            </p>
            );
  }
} babel-polyfill 在出現 regeneratorRuntime is not defined 需引入
在 createStore 的地方
需使用 applyMiddleware 來使非同步動作產生效果
反則不會正常動作
codeimport "babel-polyfill"; //regeneratorRuntime is not defined import React from 'react'; import ReactDOM from 'react-dom'; import {createStore , applyMiddleware} from 'redux'; import {Provider} from 'react-redux'; import Counter from './container/container' import reducer from './reducer/index' import thunk from 'redux-thunk'; const store = createStore( reducer, applyMiddleware(thunk) ); ReactDOM.render( <Provider store={store}> <Counter /> </Provider>, document.getElementById('app') );
範例 
沒有留言:
張貼留言