When it comes to learning ReactJS with Redux, there are numerous really helpful documents and tutorials online, including 'Redux Usage with React'
However, when closing the gap between the online examples and production code, a gaping hole emerges: "How do you get data in and out of your React + Redux app?".
Whether you are building a React native app or using React for the web you reach a point where you need to read data that represents the current state, and then save changes to that data.
I found the documentation at this point a little fuzzy, with reference being made to 'side-effects'. Now, I personally see the loading and saving of data in an application as more than a side effect. But I kept on coming back to diagrams like this:
And this:
But what I really needed was a diagram like this:
Now the 'side-effect' nature of this data access becomes clear.
If you are on this same journey of discovery, hopefully you will find the steps below helpful.
The examples are for React on the web, but the principle is the same for React native.
(Apologies to JavaScript purists, but these examples are in TypeScript)
1. Use redux-thunk when you configure the store.
2. Use superagent (or similar) in an API class to make the http call.
3. Create an Action Creator which handles the response of the API function.
3b. Possibly including a reducer to update the store.
4. Create an ActionCreator which calls the API function.
5. Wire up the action in the Container Component.
6. When the response for the call returns, dispatch another event to update the store.
However, when closing the gap between the online examples and production code, a gaping hole emerges: "How do you get data in and out of your React + Redux app?".
Whether you are building a React native app or using React for the web you reach a point where you need to read data that represents the current state, and then save changes to that data.
I found the documentation at this point a little fuzzy, with reference being made to 'side-effects'. Now, I personally see the loading and saving of data in an application as more than a side effect. But I kept on coming back to diagrams like this:
Apologies, but I can't recall the original source for this. If it is you, please do get in touch and I will give you the credit. |
And this:
But what I really needed was a diagram like this:
Now the 'side-effect' nature of this data access becomes clear.
If you are on this same journey of discovery, hopefully you will find the steps below helpful.
The examples are for React on the web, but the principle is the same for React native.
(Apologies to JavaScript purists, but these examples are in TypeScript)
1. Use redux-thunk when you configure the store.
export default function configureStore(): Redux.Store
return createStore rootReducer, applyMiddleware( ReduxThunk // lets us dispatch functions for calls to web server ) ); } |
export default class xxxApi {
public constructor(private baseUrl: string) {} public getAbc(): Promise return new Promise((resolve: any, reject: any): any => { let request = Superagent.get(this.baseUrl + '/abc').send({…}); request.set({ … }); request.end((error: any, response: any) => {…}); }); } } |
export function receiveAbc(json: any): IAction
return { type: xxxTypes.LOAD_ABC, payload: json, }; } |
export default function AbcReducer(state:AbcState, action: IAction
switch (action.type) { case xxxypes.LOAD_ABC: { // immutable state change } } } |
export function fetchAbc(): any {
// thunk middleware passes dispatch, state & container in return function(dispatchEvent: Function, getState: Function, container: dependencyContainer): any { let state: IStoreState = getState(); // in actions you can read from the store if you need to let api: new XxxAPI(state.config.baseUrl); api.getAbc() .then((json: any) => { // process result here }); }; } |
const mapDispatchToProps = (dispatchEvent: any): xxxProps => {
return { ... goGetAbc: () => { dispatchEvent(xxxActions.fetchAbc()); } }; }; |
export function fetchAbc(): any {
return function(dispatchEvent: Function, getState: Function): any { let state: IStoreState = getState(); let api: new XxxAPI(state.config.baseUrl); api.getAbc() .then((json: any) => { // process data dispatchEvent(receiveAbc(json)); // removing loading indicator (or similar) dispatchEvent(updateUiLoadingStatus()); }); }; } |
Comments
Post a Comment