This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const reducer = (state, { type, payload }) => { | |
| switch (type) { | |
| case 'ADD_FOOD_ITEM': | |
| return { | |
| foodItems: [ | |
| ...state.foodItems, | |
| payload | |
| ] | |
| } | |
| default: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const App = ({ foodItems, addFoodItem }) => ( | |
| <div> | |
| <ul> | |
| { | |
| foodItems.map(({ name, quantity }) => ( | |
| <li>{name}, quantity: {quantity}</li> | |
| )) | |
| } | |
| </ul> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const FOOD_ITEMS_FETCH_PENDING = 'FOOD_ITEMS_FETCH_PENDING' | |
| const FOOD_ITEMS_FETCH_COMPLETE = 'FOOD_ITEMS_FETCH_COMPLETE' | |
| const FOOD_ITEMS_FETCH_ERROR = 'FOOD_ITEMS_FETCH_ERROR' | |
| const FOOD_ITEMS_ADD_PENDING = 'FOOD_ITEMS_ADD_PENDING' | |
| const FOOD_ITEMS_ADD_COMPLETE = 'FOOD_ITEMS_ADD_COMPLETE' | |
| const FOOD_ITEMS_ADD_ERROR = 'FOOD_ITEMS_ADD_ERROR' | |
| // … | |
| const addFoodItem = item => (dispatch) => { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Here we have a function which accepts a map of async states to action types | |
| // as well as a thunk creator. It will yield a new thunk creator which wraps | |
| // the provided one with our async state logic | |
| const asyncActionCreator = (asyncTypes, createThunk) => (...args) => { | |
| const thunk = createThunk(...args); | |
| return (dispatch) => { | |
| dispatch({ type: asyncTypes.pending }) | |
| // We assume here that the wrapped thunk produces a Promise |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const fetchFoodItems = createActionCreator( | |
| { | |
| pending: FOOD_ITEMS_FETCH_PENDING, | |
| complete: FOOD_ITEMS_FETCH_COMPLETE, | |
| error: FOOD_ITEMS_FETCH_ERROR, | |
| }, | |
| () => () => foodService.fetchFoodItems() | |
| ) | |
| const addFoodItem = createActionCreator( |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Similar to the higher-order action creator, we accept a mapping of async | |
| // states and action types, except this time, for convenience, in reverse. | |
| // We then yield a reducer | |
| const loadStateReducer = (asyncStates) => { | |
| return (state = { loading: false, loaded: false, data: null }, action) { | |
| const asyncState = asyncStates[action.type] | |
| switch (asyncState) { | |
| case 'pending': | |
| return { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const { combineReducers } = require('redux') | |
| const foodItemsLoadState = loadStateReducer({ | |
| FOOD_ITEMS_FETCH_PENDING: 'pending', | |
| FOOD_ITEMS_FETCH_ERROR: 'error', | |
| FOOD_ITEMS_FETCH_COMPLETE: 'complete' | |
| }) | |
| const foodItemAddState = loadStateReducer({ | |
| FOOD_ITEMS_ADD_PENDING: 'pending', |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const getAsyncFoodItems = state => state.foodItems | |
| const getAsyncCookware = state => state.cookware | |
| // Let’s introduce a new async resource containing fun facts about food | |
| const getAsyncFunFactsById = state => state.funFactsById |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const getFoodItemListViewState = createAsyncSelector({ | |
| foodItems: getAsyncFoodItems, | |
| funFactsById: getAsyncFunFactsById | |
| }) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const getAsyncFoodItemsWithFacts = createAsyncSelector( | |
| { | |
| foodItems: getAsyncFoodItems, | |
| funFactsById: getFunFactsById | |
| }, | |
| ({ foodItems, funFactsById }) => ( | |
| mergeFunFactsIntoFoodItems(foodItems, funFactsById) | |
| )) | |
| ) |