React-Redux project for Udacity React-nanodegree
This project is based off of the Readable API Server starting template
which contained the code for the backend api server that is interacted with for the development of the project.
The project makes the decision to combine the api-server and frontend application into one central project for both ease of development and
management of source control. Each individual project, api-server and frontend, maintain their own dependencies and are tied together by npm
scripts found at the root of the project.
The project makes the purposeful decision of grouping reusable components into a common controls directory which are all exported by the root
index.js file for each of locating assets. An example of this can be found below:
import {
PostDetailPage,
PostCommentPage,
FullPageDialog,
PostForm,
CommentForm
} from '../components/controls'
yarn install
yarn start
Overall the layout and design of the app is typical for react, redux, react-router apps. The major difference that may be noted is the concise
effort to maintain reducers that are more deterministic and easily testable by removing switch and if statements and relying specifically
on language features to maximize testability and determinism.
I am unsure if this deterministic reducer style is worth maintaining but felt it was interesting to try out for this project. An
example is found below:
//all functions exported for testing purposes
export const loadPosts = (state, {posts})=>posts;
export const loadPostsForCategory = (state, {posts})=>([
...state.filter(item=>posts[0] && posts[0].category && item.category !== posts[0].category),
//this is a null guard for the spread operator to ensure proper array shape on the event of a null object
...(posts || [])
]);
export const addPost = (state, {post})=>([
...state,
post
]);
export const editPost = (state, {post})=>([
...state.filter(item=>post && item.id !== post.id),
//this is a null guard for the spread operator to ensure proper array shape on the event of a null object
...(post && [post] || []) // eslint-disable-line no-mixed-operators
]);
const reducer = {
[LOAD_ALL_POSTS]: loadPosts,
[LOAD_POSTS_FOR_CATEGORY]: loadPostsForCategory,
[LOAD_POST]: editPost,
[ADD_POST]: addPost,
[EDIT_POST]: editPost,
[UPVOTE_POST]: editPost,
[DOWNVOTE_POST]: editPost,
[DELETE_POST]: editPost
};
export default (state=[], {type, ...action})=>
reducer[type] ? reducer[type](state, action) : state;
Information about the API server and how to use it can be found in its README file.
This repository is used for a nanodegree program that I am participating in so I will not be accepting pull requests.