2016-11-29 58 views
0

我的代码如下:如何使Redux的外部API调用反应

const LOAD = 'redux-example/LOAD'; 
const LOAD_SUCCESS = 'redux-example/LOAD_SUCCESS'; 
const LOAD_FAIL = 'redux-example/LOAD_FAIL'; 
import axios from 'axios'; 
const initialState = { 
    loaded: false 
}; 
export default function info(state = initialState, action = {}) { 
    switch (action.type) { 

    case LOAD: 
    return { 
    ...state, 
    loading: true 
    }; 
    case LOAD_SUCCESS: 
    return { 
    ...state, 
    loading: false, 
    loaded: true, 
    data: action.result 
    }; 
case LOAD_FAIL: 
    return { 
    ...state, 
    loading: false, 
    loaded: false, 
    error: action.error 
    }; 
default: 
    return state; 
} 
} 
export function load() { 
    return { 
     types: [LOAD, LOAD_SUCCESS, LOAD_FAIL], 
     promise: (client) => client.get('http://example.com/getdata') 
    }; 
} 

我使用https://github.com/erikras/react-redux-universal-hot-example例如作为入门套件。我希望基于api调用example.com/api.But,但我无法通过异步调用来实现。我在中间件中遇到错误,无法读取未定义的promise。我的中间件代码如下所示。

export default function clientMiddleware(client) { 
return ({dispatch, getState}) => { 
return next => action => { 
    if (typeof action === 'function') { 
     return action(dispatch, getState); 
    } 
    const { promise, types, ...rest } = action; // eslint-disable-line no-redeclare 
    if (!promise) { 
     return next(action); 
    } 
    const [REQUEST,SUCCESS,FAILURE] = types; 
    next({...rest, type: REQUEST}); 
    const actionPromise = promise(client); 
    actionPromise.then(  
     (result) => next({...rest, result, type: SUCCESS}), 
     (error) => next({...rest, error, type: FAILURE}) 
    ).catch((error)=> { 
     console.error('MIDDLEWARE ERROR:', error); 
     next({...rest, error, type: FAILURE}); 
    }); 
    return actionPromise; 
}; 
}; 
} 

MY分量代码是如下

import React, {Component, PropTypes} from 'react'; 
import {bindActionCreators} from 'redux'; 
import {connect} from 'react-redux'; 
import {load} from 'redux/modules/info'; 

@connect(state => ({info: state.info.data}),dispatch =>  bindActionCreators({load}, dispatch)) 

export default class InfoBar extends Component { 
static propTypes = { 
info: PropTypes.object, 
load: PropTypes.func.isRequired 
} 
render() { 
const {info, load} = this.props; // eslint-disable-line no-shadow 
const styles = require('./InfoBar.scss'); 
return (
    <div className={styles.infoBar + ' well'}> 
    <div className="container"> 
     This is an info bar 
     {' '} 
     <strong>{info ? info.message : 'no info!'}</strong> 
     <span className={styles.time}>{info && new Date(info.time).toString()}</span> 
     <button className="btn btn-primary" onClick={load}>Reload from server</button> 
    </div> 
    </div> 
); 
} 
} 
+0

恐怕你碰到相同来源的限制,当您执行对远程端点的异步HTTP请求。看看[公共维基有关同源规避](http://stackoverflow.com/questions/3076414/ways-to-circumvent-the-same-origin-policy),也许你会得到一个想法如何代理您的请求或以另一种方式克服限制。 –

+0

我已经使用该入门工具包,并且您的代码看起来正确。我同意上面的@Rishat ......看起来你做的都是正确的,但是你可能正在做一个失败的跨域REST调用。 “MIDDLEWARE ERROR”之后,您是否在控制台中获得更多信息? –

+0

我没有得到交叉原点错误,但我确实得到“无法读取属性'承诺'的未定义”错误。 API适用于跨域访问。 – user1820017

回答

-1

这仅仅是减速机。你会想创建一个动作。一个动作会触发将使Redux商店更新其状态的事件。终极版的是这样的基本流程是这样:

  • 安装组件
  • 派遣行动
  • 反过来
  • 调度操作将更新通过Provider组件商店
  • 这将触发重新-render组件。

以下是使用fetch的基本示例。

import fetch from 'isomorphic-fetch'; 

export function getUsers() { 
    return dispatch => { 
    dispatch({ type: REQUEST_USERS }); 

    return fetch('/api/v1/users') 
     .then(res => res.json()) 
     .then(users => { 
     dispatch({ type: RECEIVE_USERS, payload: users }); 
     return users; 
     }); 
    } 
} 

然后你可以在你的组件级别的项目中调用它。

import { getUsers } from 'actions/users'; 

class UserList extends Component { 
    componentDidMount() { dispatch(getUsers()) } 
} 

退房的example

+0

我有上面的代码的客户端中间件,也与该示例如果我打电话localhost api的作品 – user1820017

+0

,但它不适用于外部api调用。 localhost api有这样的代码导出默认函数loadInfo(){ 返回新的Promise((resolve)=> { resolve({来自api服务器', time:Date.now() } ); }); } – user1820017

+0

这不是一个正确的答案,因为他正在使用redux-tunk作为中间件。并打破流动 – JoseAPL