Async Thunk Redux
setsubscribed redux-thunk. .
.
const subscribed = { type: 'SET_SUBSCRIBED', subscribed: true }
API.
API, .
- , actionSubscribed thunk action.
, decx-thunk, , thunk.
Action Creators
, , - , .
"" . , .
, .
function addTodo(text) {
return {
type: ADD_TODO,
text
}
}
, . , redux, .
toDos . todo, .
const walkDogAction = addTodo('walk the dog')
console.log(walkDogAction)
*
* { type: 'ADD_TO_DO, text: 'walk the dog' }
*
, .
, , , .
store.dispatch(walkDogAction)
.
, todo, , .
? , , , .
Redux
() ()?
- , . - , .
, , - ? :
, , , , addtodo , .
, , . ? .
. . , , .
Thunk Action?
, - , . , getState.
Here is the code inside Redux thunk that does this:
if (typeof action === 'function') {
return action(dispatch, getState, extraArgument);
}
setSubscribed thunk, , .
, thunk . , .
. action decux thunk , aour async-, HTTP-. , , , ()
actions.js
export function fetchSomethingRequest () {
return {
type: 'FETCH_SOMETHING_REQUEST'
}
}
export function fetchSomethingSuccess (body) {
return {
type: 'FETCH_SOMETHING_SUCCESS',
body: body
}
}
export function fetchSomethingFailure (err) {
return {
type: 'FETCH_SOMETHING_FAILURE',
err
}
}
export function fetchSomething () {
return function (dispatch) {
dispatch(fetchSomethingRequest())
return fetchSomething('http://example.com/').then(function (response) {
if (response.status !== 200) {
throw new Error('Bad response from server')
} else {
dispatch(fetchSomethingSuccess(response))
}
}).catch(function (reason) {
dispatch(fetchSomethingFailure(reason))
})
}
}
, , , - action decux. , , .
Mock Redux
store store redux-mock-store .
import configureStore from 'redux-mock-store';
, .
thunk action, redux-thunk , thunk. , , .
const middlewares = [ReduxThunk];
const mockStore = configureStore(middlewares);
mock store store.getActions, .
, -, .
, thunk action Mocha
, thunk -. , . Then, , thunk.
, , , action decux thunk, , .
import configureMockStore from 'redux-mock-store'
import thunk from 'redux-thunk'
import fetchMock from 'fetch-mock'
import expect from 'expect'
import { fetchSomething } from './actions.js'
const middlewares = [ thunk ]
const mockStore = configureMockStore(middlewares)
describe('Test thunk action creator', () => {
it('expected actions should be dispatched on successful request', () => {
const store = mockStore({})
const expectedActions = [
'FETCH_SOMETHING_REQUEST',
'FETCH_SOMETHING_SUCCESS'
]
fetchMock.get('*', { response: 200 })
return store.dispatch(fetchSomething())
.then(() => {
const actualActions = store.getActions().map(action => action.type)
expect(actualActions).toEqual(expectedActions)
})
fetchMock.restore()
})
it('expected actions should be dispatched on failed request', () => {
const store = mockStore({})
const expectedActions = [
'FETCH_SOMETHING_REQUEST',
'FETCH_SOMETHING_FAILURE'
]
fetchMock.get('*', { response: 404 })
return store.dispatch(fetchSomething())
.then(() => {
const actualActions = store.getActions().map(action => action.type)
expect(actualActions).toEqual(expectedActions)
})
fetchMock.restore()
})
})
, Redux thunk .
thunk action , , .
- , HTTP- 200, .
Common Gotcha Thunks - Promises Action Creators
, Promises , .
export function thunkActionCreator () {
return function thatIsCalledByreduxThunkMiddleware() {
return function returnsPromise()
.then(function (fulfilledResult) {
})
}
}
, , :
TypeError: Cannot read property 'then' of undefined - store.dispatch - returns undefined
, , .then. , , . , , . Then on undefined. , undefined, , return.
, return promises.