简体   繁体   English

react + redux + axios:动作不发送到减速器

[英]react + redux + axios: actions not sent to reducers

I am building a React+Redux app.我正在构建一个 React+Redux 应用程序。 I am using axios to make api requests.我正在使用 axios 发出 api 请求。 I am trying to make three api requests, one after the other.我正在尝试一个接一个地发出三个 api 请求。 The first needs to be complete before the second two can run, because the first returns a user object that the second two use in their request.第一个需要在第二个可以运行之前完成,因为第一个返回一个用户对象,后两个在他们的请求中使用。

I run getUser, and only the app state related to getUser gets updated.我运行 getUser,只有与 getUser 相关的应用程序状态才会更新。 But the other two apis don't update the app state as they should.但是其他两个 api 没有像他们应该的那样更新应用程序状态。 Neither getUserScores nor getCustomerEquations actually change the state. getUserScores 和 getCustomerEquations 实际上都不会改变状态。 From my gulp process I know that all the API requests are successful.从我的 gulp 过程中我知道所有 API 请求都成功了。 From a console.log I know that the axios promises are created.从 console.log 我知道创建了 axios 承诺。

So for some unknown reason the objects my functions are returning aren't making it to the reducers.因此,由于某种未知原因,我的函数返回的对象没有进入减速器。 What is missing here?这里缺少什么?

Thanks for helping!感谢您的帮助!

index.js:索引.js:

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import ReduxPromise from 'redux-promise';   //this is middleware

import App from './containers/app';
import reducers from './reducers/index';

const createStoreWithMiddleware = applyMiddleware(ReduxPromise)(createStore);

ReactDOM.render(
  <Provider store={createStoreWithMiddleware(reducers)}>
    <App />
  </Provider>
  , document.getElementById('container'));

actions/index:动作/索引:

import axios from 'axios';

export function getUser(email) {
  let url = 'api/users?user__email=' + email;

  axios.get(url)
      .then((response) => {
        getCustomerEquations(response.data[0].customer);
        getUserScores(response.data[0].id);
      });

  let request = axios.get(url);

  return {
    type: 'GET_USER',
    payload: request
  }
}

export function getUserScores(userId) {
  let url = '/api/user_scores?user__id=' + userId;


  let request = axios.get(url);

  return {
    type: 'GET_USER_SCORES',
    payload: request
  };
}

export function getCustomerEquations(customerId) {
  let url = '/api/equations?customer__id=' + customerId;
  let request = axios.get(url);

  return {
    type: 'GET_CUSTOMER_EQUATIONS',
    payload: request
  };
}     

reducers/reducer-getUserScores:减速器/减速器-getUserScores:

import React from 'react';
import { GET_USER_SCORES } from '../actions/index';

export default function(state = ["d"], action = {}) {
  switch(action.type) {
    case GET_USER_SCORES:
      // do not manipulate existing state. create a new one
      //ES6 way to write 'return state.concat(action.payload.data);

      console.log('userScores in Reducer:', action.payload.data);
      return action.payload.data;
    default:
      console.log('userScores-Reducer: the case didnt match', action.type);

  }
  return state;
}

you need to return a function instead of an action and dispatch the action only when your criteria is matched.您需要返回一个函数而不是一个动作,并且仅当您的条件匹配时才调度该动作。 You can try writing your own simple middle version of middle where,or you can use thunk https://github.com/gaearon/redux-thunk您可以尝试编写自己的简单中间版本的中间版本,或者您可以使用 thunk https://github.com/gaearon/redux-thunk

A single action might trigger several state changes.单个操作可能会触发多个状态更改。 For example, check the following:例如,检查以下内容:

function firstReducer(state, action) {
    switch (action.type) {
        case ACTION_X:
            // handle action x
    }
}

function secondReducer(state, action) {
    switch (action.type) {
        case ACTION_X:
            // handle action x
    }
}

function thirdReducer(state, action) {
    switch (action.type) {
        case ACTION_X:
            // handle action x
    }
}

In your case, use GET_USER_SCORES_FULFILLED instead of GET_USER_SCORES .在您的情况下,请使用GET_USER_SCORES_FULFILLED而不是GET_USER_SCORES So switch-case will be the following:所以 switch-case 将如下所示:

switch(action.type) {
    case GET_USER_SCORES_FULFILLED:
      // do not manipulate existing state. create a new one
      //ES6 way to write 'return state.concat(action.payload.data);

      console.log('userScores in Reducer:', action.payload.data);
      return action.payload.data;
      break;

    default:
      console.log('userScores-Reducer: the case didnt match', action.type);

  }

Check the following links, might be helpful.检查以下链接,可能会有所帮助。

Looks like you do not return or await your promises in the actions/index.js file看起来你没有在actions/index.js文件中返回或等待你的承诺

import axios from 'axios';

export async function getUser(email) {
  let url = 'api/users?user__email=' + email;

  // you are doing it once
  const response = await axios.get(url)
  getCustomerEquations(response.data[0].customer);
  getUserScores(response.data[0].id);

  // why do it again ?
  let request = await axios.get(url);

  return {
    type: 'GET_USER',
    payload: request
  }
}

export async function getUserScores(userId) {
  let url = '/api/user_scores?user__id=' + userId;


  let request = await axios.get(url);

  return {
    type: 'GET_USER_SCORES',
    payload: request
  };
}

export async function getCustomerEquations(customerId) {
  let url = '/api/equations?customer__id=' + customerId;
  let request = await axios.get(url);

  return {
    type: 'GET_CUSTOMER_EQUATIONS',
    payload: request
  };
}

Or if your node version does not support async await:或者,如果您的节点版本不支持异步等待:

import axios from 'axios';

export function getUser(email) {
  let url = 'api/users?user__email=' + email;

  return axios.get(url)
  .then((response) => {
    getCustomerEquations(response.data[0].customer);
    getUserScores(response.data[0].id);
    return axios.get(url).then(request => {
      return {
        type: 'GET_USER',
        payload: request
      };
    });
  });
}

export function getUserScores(userId) {
  let url = '/api/user_scores?user__id=' + userId;

  return axios.get(url).then(request => {
    return {
      type: 'GET_USER_SCORES',
      payload: request
    };
  });
}

export function getCustomerEquations(customerId) {
  let url = '/api/equations?customer__id=' + customerId;
  return axios.get(url).then(request => {
    return {
      type: 'GET_CUSTOMER_EQUATIONS',
      payload: request
    };
  });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM