天天看點

redux-promise 中間件

首先引入redux-promise

import promiseMiddleware from 'redux-promise';
           

其次建立store

let {getState,subscribe,dispatch} = createStore(
    chatReducer,
    applyMiddleware(thunk,promiseMiddleware),
);
           

applyMiddleware它是Redux的原生方法,作用是将所有中間件組成一個數組,依次執行。

參數的作用如下:

  1. thunk 異步中間件
  2. promiseMiddleware 異步中間件

redux-promise

讓Action Creator傳回一個Promise,如下

funs(){
    return function(dispatch){
        return new Promise((resolve,reject)=>{
            dispatch({
                type: 'TEXT',
                payLoad: 'titile starting.........'
            });
            getData().then(res => {
                console.log('res',res);
                dispatch({
                    type: 'TEXT',
                    payLoad: res
                })
            }).catch(err => {
                dispatch({
                    type: 'TEXT',
                    payLoad: 'titile errors........'
                })
            })
        })
    }
}
           

用箭頭函數也可以這樣實作:

funs=()=>dispatch=> new Promise((resolve,reject)=>{
    dispatch({
        type: 'TEXT',
        payLoad: 'titile starting.........'
    });
    getData().then(res => {
        console.log('res',res);
        dispatch({
            type: 'TEXT',
            payLoad: res
        })
    }).catch(err => {
        dispatch({
            type: 'TEXT',
            payLoad: 'titile errors........'
        })
    })
})
           

全部代碼:

import 'antd/dist/antd.css';
import React,{Component} from 'react';
import ReactDOM from 'react-dom';
import {Button} from 'antd';
import App from './App';
import { createStore,combineReducers,applyMiddleware } from 'redux';

import createLogger from 'redux-logger';
import thunk from 'redux-thunk';
import promiseMiddleware from 'redux-promise';



const text = (state=0,action)=>{
    const {type,payLoad} = action;
    switch(type){
        case 'TEXT':
            return Object.assign({},state,{userName:payLoad});
        default:
            return state;
    }
}

const chatReducer = combineReducers({
    text
})

let {getState,subscribe,dispatch} = createStore(
    chatReducer,
    applyMiddleware(thunk,promiseMiddleware,createLogger),
);

function getData(){
    console.log('getData');
    var url = 'https://douban.uieee.com/v2/movie/in_theaters';
    var url = 'http://www.weather.com.cn/data/sk/101010100.html';

    return fetch(url).then((res)=>{
        return res.json()
    }).then(data=>{
        console.log('data',data);
        return data.weatherinfo.city;
    })
}

const TextContent =({value,onText})=>{
    return  <div>
                <h1>{value.text.userName}</h1>
            </div>
}

class Content extends Component{
    constructor(props){
       super(props);
    }
    clickEvent=()=>{
        dispatch(this.funs());
    }
    funs(){
        return function(dispatch){
            return new Promise((resolve,reject)=>{
                dispatch({
                    type: 'TEXT',
                    payLoad: 'titile starting.........'
                });
                getData().then(res => {
                    console.log('res',res);
                    dispatch({
                        type: 'TEXT',
                        payLoad: res
                    })
                }).catch(err => {
                    dispatch({
                        type: 'TEXT',
                        payLoad: 'titile errors........'
                    })
                })
            })
        }
    }

    render(){
        return (
            <div>
                <TextContent
                    value={getState()}
                />
                <Button onClick={this.clickEvent}>點選</Button>
            </div>
        )
    }
}

const render=()=>{
    ReactDOM.render(
        <Content/>,
        document.getElementById('root')
    )
}
render();
subscribe(render);
           

還有另外一種寫法:

Action對象的payLoad屬性是一個Promise對象。

要從redux-actions子產品引入createAction這個方法。

import { createAction } from 'redux-actions';
           

重點代碼如下:

componentDidMount(){
    //發出同步
    dispatch(this.funs());
    //發出異步
    var url = 'http://www.weather.com.cn/data/sk/101010100.html';
    dispatch(createAction(
        fetch(url).then((res)=>{
            console.log('異步res',res);
            return res.json();
        })
    ));
}
           

全部代碼

import 'antd/dist/antd.css';
import React,{Component} from 'react';
import ReactDOM from 'react-dom';
import {Button} from 'antd';
import App from './App';
import * as serviceWorker from './serviceWorker';
import { createStore,combineReducers,applyMiddleware } from 'redux';

import createLogger from 'redux-logger';
import thunk from 'redux-thunk';
import promiseMiddleware from 'redux-promise';
import { createAction } from 'redux-actions';


const text = (state=0,action)=>{
    const {type,payLoad} = action;
    switch(type){
        case 'TEXT':
            return Object.assign({},state,{userName:payLoad});
        default:
            return state;
    }
}

const chatReducer = combineReducers({
    text
})

let {getState,subscribe,dispatch} = createStore(
    chatReducer,
    applyMiddleware(thunk,promiseMiddleware,createLogger),
);

function getData(){
    console.log('getData');
    var url = 'https://douban.uieee.com/v2/movie/in_theaters';
    var url = 'http://www.weather.com.cn/data/sk/101010100.html';

    return fetch(url).then((res)=>{
        return res.json()
    }).then(data=>{
        console.log('data',data);
        return data.weatherinfo.city;
    })
}

const TextContent =({value,onText})=>{
    return  <div>
                <h1>{value.text.userName}</h1>
            </div>
}

class Content extends Component{
    constructor(props){
       super(props);
    }
    componentDidMount(){
        //發出同步
        dispatch(this.funs());
        //發出異步
        var url = 'http://www.weather.com.cn/data/sk/101010100.html';
        dispatch(createAction(
            fetch(url).then((res)=>{
                console.log('異步res',res);
                return res.json();
            })
        ));
    }
    clickEvent=()=>{
        dispatch(this.funs());
    }
    // funs(){
    //     return function (dispatch) {
    //         dispatch({
    //             type: 'TEXT',
    //             payLoad: 'titile starting.........'
    //         });
    //         getData().then(res => {
    //             console.log('res',res);
    //             dispatch({
    //                 type: 'TEXT',
    //                 payLoad: res
    //             })
    //         }).catch(err => {
    //             dispatch({
    //                 type: 'TEXT',
    //                 payLoad: 'titile errors........'
    //             })
    //         })
    //     }
    // }

    // funs(){
    //     return function(dispatch){
    //         return new Promise((resolve,reject)=>{
    //             dispatch({
    //                 type: 'TEXT',
    //                 payLoad: 'titile starting.........'
    //             });
    //             getData().then(res => {
    //                 console.log('res',res);
    //                 dispatch({
    //                     type: 'TEXT',
    //                     payLoad: res
    //                 })
    //             }).catch(err => {
    //                 dispatch({
    //                     type: 'TEXT',
    //                     payLoad: 'titile errors........'
    //                 })
    //             })
    //         })
    //     }
    // }

    //箭頭函數
    funs=()=>dispatch=> new Promise((resolve,reject)=>{
        dispatch({
            type: 'TEXT',
            payLoad: 'titile starting.........'
        });
        getData().then(res => {
            console.log('res',res);
            dispatch({
                type: 'TEXT',
                payLoad: res
            })
        }).catch(err => {
            dispatch({
                type: 'TEXT',
                payLoad: 'titile errors........'
            })
        })
    })

    render(){
        return (
            <div>
                <TextContent
                    value={getState()}
                />
                <Button onClick={this.clickEvent}>點選</Button>
            </div>
        )
    }
}

const render=()=>{
    ReactDOM.render(
        <Content/>,
        document.getElementById('root')
    )
}
render();
subscribe(render);

serviceWorker.unregister();