2016-03-31 10 views
5

Usando una combinazione di Reagire, Redux e Thunk, ho il seguente:Dov'è il posto giusto per modificare i dati di risposta in redux?

actions.js

import $ from 'jquery'; 
import * as types from '../constants/ActionTypes'; 
import { API_PATH } from '../constants/Config'; 

export function coursesLoaded(courses) { 
    return { type: types.COURSES_LOADED, courses }; 
} 

export function fetchData() { 
    return (dispatch) => { 
     return $.getJSON(API_PATH).then((response) => { 
      dispatch(coursesLoaded(response.result)); 
     }); 
    }; 
} 

reducer.js

import { routerReducer as routing } from 'react-router-redux'; 
import { combineReducers } from 'redux'; 
import * as types from '../constants/ActionTypes'; 

const initialState = { 
    courses: [], 
}; 

function main(state = initialState, action) { 
    switch(action.type) { 
     case types.COURSES_LOADED: 
      return { 
       ...state, 
       courses: action.courses, 
      }; 
     default: 
      return state; 
    } 
} 

const rootReducer = combineReducers({ main, routing }); 

export default rootReducer; 

I due frammenti di sopra sit bene, e mi sento come si allineano alle intenzioni di Redux. Voglio ora apportare alcune modifiche ai campi che vengono restituiti nella risposta, prima che colpiscano i contenitori.

Ad esempio, la risposta potrebbe essere:

[ 
    { code: "R101", name: "Intro to Redux", author: "Dan" }, 
    { code: "R102", name: "Middleware", author: "Dan" }, 
] 

E voglio cambiarlo (semplice esempio per semplicità):

[ 
    { code: "R101", name: "Intro to Redux", author: "Dan", additionalProperty: "r101_intro_to_redux" }, 
    { code: "R102", name: "Middleware", author: "Dan", additionalProperty: "r102_middleware" }, 
] 

ricerca finora

Opzione 1 Guardando l'esempio asincrono su Redux, posso vedere ere è un tocco leggero alla risposta qui: https://github.com/reactjs/redux/blob/master/examples/async/actions/index.js#L33

Opzione due Guardando le altre domande StackOverflow, che mi porta a credere tenendolo fuori delle azioni ha più senso, come riduttori dovrebbe essere quello di modificare lo stato (ma forse questo in realtà non conta come stato): Redux - where to prepare data

Opzione Tre ho una inclinazione che questo è il lavoro di middleware - è che è così normalizr gestisce, ma non riesco a trovare alcuna? esempi di middleware non passivi. Se il middleware è disponibile qui, il middleware dovrebbe inviare qualche tipo di azione SET_STATE o è libero di aggiornare lo stato proprio lì nel middleware?

EDIT

sperimentato con qualche middleware, come ad esempio:

import { lowerCase, snakeCase } from 'lodash'; 
import * as types from '../constants/ActionTypes'; 

    export default store => next => action => { 
     if(action.type == types.COURSES_LOADED) { 
      action.courses = action.courses.map((course) => { 
       course.additionalProperty = snakeCase(lowerCase(`${course.code} ${course.name}`)); 
       return course; 
      }); 
     } 
     return next(action); 
    } 

Sembra funzionare bene - è questa infatti l'intenzione di middleware? La domanda originale vale - dove è il posto ideale?

+1

Suggerirei di estrarre la logica di recupero API in un 'DataService', che è anche in grado di modificare l'oggetto JSON restituito. Di conseguenza il tuo '$ .getJSON (API_PATH)' diventa 'DataService.getMyData (path)', e 'then()' ha già i dati formattati correttamente. – lux

risposta

9

Per quanto mi riguarda, faccio questo genere di cose nell'azione (o coursesLoaded o fetchData).

Qui ci sono le ragioni per le quali:

  • Questo non è il negozio di materiale, questo è solo la gestione dei dati esterni, quindi nulla a che vedere con riduttori che dovrebbero cambiare lo stato del negozio
  • diversi riduttori potrebbe effettivamente avere gli stessi dati corretti, immagina di avere un altro riduttore che raccolga tutti gli additionalProperty per scopi di acquisizione, ad esempio, così facendo nell'azione garantisce che i dati corretti vengano inviati a tutti i riduttori.
  • Questo non è un tipico lavoro per un middleware, questo è solo specifico per un'azione, mentre il middleware sarebbe utile se fosse usato allo stesso modo da un gruppo di azioni. Inoltre l'uso del middleware è più oscuro e lo separa dal lettore. Avere un'azione-> riduttore è molto più semplice e non presenta alcuno svantaggio principale.
+0

Hmm, mi piace molto quel modo di pensare. Non ho ancora usato reagire/ridi abbastanza da ragionare su come affrontare vari problemi ancora – Chris

+0

Grazie per il tuo aiuto – Chris

Problemi correlati