使用redux调用api

时间:2017-11-24 19:59:41

标签: javascript reactjs react-native react-redux react-router-redux

我将使用redux致电api: 我使用了axioshistoryreact-reduxreact-router-nativereact-routerredux-promise-middlewareredux-thunk组件来使用api调用redux: 我创建了Reducers文件夹并将我的所有reducer文件放在他们自己的文件中,然后将它们组合在一个像这样的主文件中 这是我的 generateoptReducer.js 文件:

const initialState = {
    data: {},
    error: null,
    status: null
};
import {generateOTP} from '../Actions/api';
export default function reducer(state = initialState, action) {

    switch (action.type) {
        case (action.type === 'GENERATEOTP_PENDING' || {}).input:
            // Action is pending (request is in progress)
            return {...state, status: 'fetching',methodes:'done1'};
        case (action.type === 'GENERATEOTP_FULFILLED' || {}).input:
            // Action is fulfilled (request is successful/promise resolved)
            return {
                ...state,
                error: null,
                data: action.payload.data,
                status: 'success',
                methodes:'done1'
            };
            case 'generateOTP':
                // Action is fulfilled (request is successful/promise resolved)
                return {
                    ...state,
                    error: null,
                    data: action.payload.data,
                    status: 'success',
                    methodes:'done1'
                };
        case (action.type === 'GENERATEOTP_REJECTED' || {}).input:
            // Action is rejected (request failed/promise rejected)
            return {
                ...state,
                error: action.payload,
                status: 'error'
            };
        default:
            return state;
    }
};

并将它们组合在 index.js 文件中:

import { combineReducers } from 'redux';
import { routerReducer } from 'react-router-redux';

//import api from './api-reducer';


import generateotp from './generateotpReducer';
import login from './loginReducer';

export default combineReducers({
  generateotp,
  login,
  routing: routerReducer,
});

我还创建了另一个名为Action的文件夹,并将所有api放在名为 api.js 的文件中:

这是我上面的减速器动作:

export const generateOTP = (phone_number) => ({
    type: 'GENERATEOTP',
    payload: axios({
        method: 'GET',
        url: format(generate_endpoint, phone_number, serviceId),
        headers: {"Accept": "application/json","Content-Type":"application/json"}
    })
});

这也是我的商店:

import { applyMiddleware, createStore } from 'redux';
import { routerMiddleware } from 'react-router-redux';
import thunk from 'redux-thunk';
import promiseMiddleware from 'redux-promise-middleware';
import logger from 'redux-logger'
import reducers from './Reducers';

export default function configureStore(history) {
  const middleware = applyMiddleware(
    promiseMiddleware(),
    thunk,

    routerMiddleware(history));
  return createStore(reducers, {}, middleware);
}

这就是我发送动作的方式: 在我的组件文件的上面导入如下:

import { generateOTP } from "../Components/Actions/api";

并按照以下方式发送动作:

this.props.dispatch(generateOTP(formatted_phone_number));

我还在文件底部连接这样的组件:

export default connect(state => state)(SignIn)

现在我需要这个api的结果。我曾经使用componentWillReceiveProps方法来接收结果。我不知道为什么这个组件没有运行。我搜索得太多我发现一个混乱的结果,说状态没有改变,然后componentWillReceiveProps没有运行!好的是api调用成功,我可以看到日志,我可以在日志和api调用中看到%cGENERATEOTP_PENDING然后%cGENERATEOTP_FULFILLED成功,但问题出在componentWillReceiveProps (我不再运行),我曾经收到api电话的结果。

6 个答案:

答案 0 :(得分:1)

您的switch语句看起来是mailformed

case (action.type === 'GENERATEOTP_FULFILLED' || {}).input:

这将永远不会运行,因为(action.type === 'GENERATEOTP_FULFILLED' || {})将是true{}?.input始终是undefined

您需要像这样编写smth来验证一些其他参数:

switch (action.type) {
    case 'GENERATEOTP_PENDING':
        if (action.input) {
            // Action is pending (request is in progress)
            return {...state, status: 'fetching',methodes:'done1'};
        }
        break; //!
    ...
}

答案 1 :(得分:0)

componentWillReceiveProps (nextProps){

console.log('get here',nextProps. fullState)

}

像这样使用连接

function mapStateToProps(state) {
console.log('get your state here',state)
  return {
   fullState: state.appState,
  };
}

export default connect(mapStateToProps, {generateOTP})(SignIn);

答案 2 :(得分:0)

你的减速机代码看起来有些偏差。你有:

switch (action.type) {
  case (action.type === 'GENERATEOTP_PENDING' || {}).input:
      // Action is pending (request is in progress)
      return {...state, status: 'fetching',methodes:'done1'};
  case (action.type === 'GENERATEOTP_FULFILLED' || {}).input:
      // Action is fulfilled (request is successful/promise resolved)
      return {
          ...state,
          error: null,
          data: action.payload.data,
          status: 'success',
          methodes:'done1'
      };
  case 'generateOTP':
      // Action is fulfilled (request is successful/promise resolved)
      return {
          ...state,
          error: null,
          data: action.payload.data,
          status: 'success',
          methodes:'done1'
      };
  // ... etc
}

switch语句正在查看action.type,然后前两个案例尝试访问(action.type === 'ACTION_NAME' || {}).input。此语句可解析为(a Boolean instance).input{}.input。这些案例中的每一个都是" falsey",因为input不是任何这些值的属性。当代码运行时,程序将action.type(false || {}).input进行比较,这将永远不会成立,因此不会运行该案例。

我不确定你在前两种情况下想要计算什么,但是switch语句中的下一种情况看起来更正确,你只需要一个动作名称作为字符串(case 'generateOTP')。

我的假设是你的reducer代码永远不会运行,即使网络请求也是如此。

答案 3 :(得分:0)

正如上面的回答提到你的“reducer”文件看起来很奇怪。

开关案例应

switch (action.type) {
  case 'GENERATEOTP_PENDING':
    //stuff
    break;
  case 'GENERATEOTP_FULFILLED':
    //stuff
    break;
  case 'generateOTP':
    //stuff
    break;

但我认为我们的另一个问题是“generateOTP”的动作 正在为减少行动设置一个“承诺”。

reducer处理它就像一个普通的数据对象。

我会处理我行动的承诺 或至少确保减速器正在处理这一承诺。

答案 4 :(得分:0)

按以下方式重构您的行动。

export function generateOTP() {
 return {
  type: 'GENERATE_OTP',
  payload:axios({
    method: 'get',
    url: 'http://10.0.2.2:3000/news',
    headers: {"Accept": "application/json"}
  }).then(success => {
    return success
  }).catch(fail => {
    return fail
 })
}

根据上述评论,必须修复减速器。

答案 5 :(得分:0)

我建议不通过this.props.dispatch调度一个动作,而只是通过dispatch(generateOTP)

如果您希望该操作在道具中可用,那么在connect方法中,您必须完全填充mapDispatchToProps函数。

例如,在我的代码中:

import * as postActions from '../actions/post'
import * as langActions from '../actions/lang'

const mapDispatchToProps = dispatch => {
  return bindActionCreators(Object.assign({},
     postActions,
     langActions,
  ), dispatch);
}

export default connect(mapStateToProps, mapDispatchToProps)(News)

但是,即使是您的情况,您也可以通过道具访问此操作,而不是通过派遣,而是通过道具的其他任何功能:

this.props.generateOTP()