A Guide For Building A React Redux CRUD App

rajaraodv
rajaraodv
Mar 6, 2016 · 10 min read

STEP 1 — Write Detailed Mocks For Each Page And Phases.

1.1 Success Phase — Detailed Mocks when things are working

1.2 Loading Phase — Detailed Mocks when they are loading

1.3 Error Phase — Detailed Mocks when there is an Error

STEP 2 — Divide Each Page Into Components

2.1 — Success Phase: Divide Each Page Into Components

2.2 — Loading Phase: Divide Each Page Into Components

2.3 — Error Phase: Divide Each Page Into Components

Redux Terms:

Redux Terms — “Actions” And “States”

{"type": "FETCH_POST", "id": 1234} // <-- Action
{"post": {"id": 1234, "title": "My Redux Post"}} // <-- state

Redux Terms — “Action Creators”

function fetchPost(id) {
return {
type: FETCH_POST,
result: makeServerRequest("http://postsServer.com/api/id")
};
}

Redux Terms — “Dispatching an Action”

//Call the "Action Creator" w/ post's id and then use it's return //value (Action JSON object) to finally dispatch it to "reducers"dispatch(fetchPost(id)) or dispatch({type:"FETCH_POST", id:1234})

Redux Terms — “Reducers”

//If the action is FETCH_POST_SUCCESS, return a new "activePost" //state w/ new post)
case FETCH_POST_SUCCESS:
return {activePost: {post: action.payload.data, error:null,
loading: false}};

PATTERN: Dealing With Async Actions

{postsList:{posts:[], loading:false, error:null}}
dispatch({“type”: “FETCH_POSTS”, loading: true})
{postList: {posts:null, error: null, loading: true}}
dispatch({"type": "FETCH_POSTS_SUCCESS", "posts":[post1, post2])
{postsList:{posts:[post1, post2], error:null, loading: false}}
dispatch({"type": "FETCH_POSTS_FAILURE", "error": "Error message"})
{postList:{posts:null, error:{msg: "Error msg"}, loading: false}}
dispatch({"type": "RESET_POST", loading: false, "post": null, "error": "Error message"})
{postList:{post:null, error:null, loading: false}}

STEP 3 — List State and Actions For Each Component (AND For Each Phase)

3.1 PostList Component — List State And Actions

{ postsList: {posts: [], error:null, loading: false} //initial state
export function fetchPosts() {
const request = axios.get(`${ROOT_URL}/posts`);
return {
type: FETCH_POSTS,
payload: request
};
}
export function fetchPostsSuccess(posts) {
return {
type: FETCH_POSTS_SUCCESS,
payload: posts
};
}
export function fetchPostsFailure(error) {
return {
type: FETCH_POSTS_FAILURE,
payload: error
};
}

3.2 PostDetails Component — List State And Actions

3.3 PostForm Component — State And Actions

3.4 Header Component — List State And Actions

STEP 4 — Create Action Creators For Each Action

//Example Action creators...export function fetchPosts() {
const request = axios.get(`${ROOT_URL}/posts`);
return {
type: FETCH_POSTS,
payload: request
};
}
export function fetchPostsSuccess(posts) {
return {
type: FETCH_POSTS_SUCCESS,
payload: posts
};
}
...

Redux Term: “Reducers”

The below function takes the current "postsList" inside "...state" and merges new "postList" and creates a **new** state(json), if the action is "FECTH_POSTS_SUCCESS"case FETCH_POSTS_SUCCESS:
return { …state, postsList: {posts: action.payload, error:null,
loading: false}
};

STEP 5 — Write Reducers For Each Action

Redux Term: “Presentational” and “Container” Components

STEP 6 — Implement Every Presentational Component

6.1 Implement Presentational Component — PostsList

6.2 Implement Presentational Component — PostDetails

6.3 Implement Presentational Component — PostForm

6.4 Implement Presentational Component — Header

STEP 7 — Create Container Component For Some/All Presentational Component

7.1 Create Container Component — PostsListContainer

7.2 Create Container Component — PostDetailsContainer

7.3 Create Container Component — PostFormContainer

7.4 Create Container Component — HeaderContainer

STEP 8 — Finally Bring Them All Together

import React from 'react'; <-- Main React lib
import ReactDOM from 'react-dom'; <-- Main React DOM lib
import { Provider } from 'react-redux';<-- Injects Redux to comps
import { createStore, applyMiddleware } from 'redux';<- Redux
import { Router, browserHistory } from 'react-router';<- Navigation
import reducers from './reducers'; <- Import reducers
import promise from 'redux-promise';
//Configure middleware w/ redux-promise for AJAX requests
const createStoreWithMiddleware = applyMiddleware(
promise
)(createStore);
const store = createStoreWithMiddleware(reducers);ReactDOM.render(
<Provider store={store}> <- Inject global redux state to comps
<Router history={browserHistory}>
<Route path=”/” component={App}> <- Wrapper for all pages
<IndexRoute component={PostsIndex} /> <-wrapper Index page
<Route path=”posts/new” component={PostsNew} /> <- New page
<Route path=”posts/:id” component={PostsShow} /> <-Details
</Route>
</Router>
</Provider>
, document.getElementById('body'));

My Other Blogs

Functional Programming

ES6

WebPack

Draft.js

React And Redux :

Salesforce

rajaraodv

Written by

rajaraodv

Trying to make Web development simple. Former Developer Advocate @Salesforce, VMware (node.js); Engineer @ Yahoo, Zimbra. Twitter: @rajaraodv

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade