2016-05-25 24 views
6

Podczas pisania funkcji redux-thunk, znanych jako thunks, istnieje wiele elementów, które można łatwo usunąć. Na przykład w większości naszych połączeń asynchronicznych API wykonujemy następujące czynności bez żadnych skutków ubocznych:Redukcja płytki redukcyjnej redux-thunk

export const LOGIN_REQUEST = 'my-app/auth/LOGIN_REQUEST'; 
export const LOGIN_RECIEVE = 'my-app/auth/LOGIN_RECIEVE'; 
export const LOGIN_FAILURE = 'my-app/auth/LOGIN_FAILURE'; 

// ... reducer code here 

export function login(loginHandle, password) { 
    return (dispatch, getState, api) => { 
    dispatch({ type: LOGIN_REQUEST }); 

    api.post('/auth/login', { loginHandle, password }).then(
     response => dispatch({ type: LOGIN_RECIEVE, response }), 
     error => dispatch({ type: LOGIN_FAILURE, error }) 
    ); 
    }; 
} 

Easy! Chociaż jak to obejmuje co najmniej 70% naszych żądań Jestem pewien, że jest to elegancki sposób abstrakcyjny z dala przydzieleniu powyższym kodem do czegoś tak (pseudo kod):

export function login(loginHandle, password) { 
    return (dispatch, getState, api) => api('POST', LOGIN_REQUEST, '/auth/login', { loginHandle, password }); 
} 

Kiedy trzeba sprawdzić stan i inne efekty uboczne możemy cofnąć do właściwego thunk. Chociaż w większości przypadków ... moglibyśmy to ograniczyć?

Jakieś eleganckie pomysły?

Odpowiedz

7

Redux Thunk pozwala wprowadzić własny argument od 2.1.0.

const api = createApi() // you would write this function 
const store = createStore(
    reducer, 
    applyMiddleware(thunk.withExtraArgument(api)) 
) 

// your action creator: 
function fetchUser(id) { 
    return (dispatch, getState, api) => { 
    // you can use api here 
    } 
} 

W przyszłości, jeśli łącznikami zbyt skomplikowane, to może warto rozważyć redux-saga lub redux-observable.

+0

Jak widzisz w powyższym pytaniu, już wstrzykiwamy nasze "api" jako argument. Problem był bardziej związany z redukcją * request, receive, fail * boilerplate – AndrewMcLagan

+0

Niestety, myślałem, że "coś takiego (pseudo-kod)" oznacza, że ​​nie zdawałeś sobie sprawy z 'withExtraArgument()' i właśnie zdarzyło ci się zasugerować podobny API . –

+0

Aby zmniejszyć liczbę żądań/braków/braków, należy sprawdzić stronę https://github.com/acdlite/redux-promise. –

0

Niestety, nie ma wspólnej metody w społeczności redux, aby podejść do tego problemu. Osobiście uważam, że ludzie nie powinni bać się pisać własnych niestandardowych opakowań wokół redux, aby radzić sobie z takimi właśnie sytuacjami.

stworzyłem bibliotekę o nazwie redux-tiles, który faktycznie ma niemal dokładnie API, jak chcesz :) Na przykład, kod będzie wyglądać następująco:

import { createTile } from 'redux-tiles'; 
const login = createTile({ 
    type: ['user', 'login'], 
    // params is an argument with which you call an action 
    fn: ({ api, params }) => api('POST', '/auth/login', params), 
}); 

Jak widać, nie ma tu stałe , a także reduktor. Te rzeczy są tworzone automatycznie, więc nie musisz tego robić, a także testować. Istnieją inne funkcje, takie jak zagnieżdżanie (na przykład ta sama funkcja będzie stosowana do pobierania elementów według identyfikatora, ale będą one poprawnie aktualizowane wewnątrz reduktora) i buforowania. Możesz sprawdzić przykłady: here.

Saga Redux też jest dobra, ale bardziej potrzebna jest reaktywność, jeśli potrzebujesz bardziej tradycyjnego podejścia, po prostu wygodniej opisać swoje działania i połączyć je bez powtarzania siebie , a następnie uważam, że moja biblioteka idealnie pasuje.