Learn more about our current job openings and benefits of working at FSL.
Detailed reviews and feedback from past and current clients.
Get to know the Management Team behind FullStack Labs.
Our step-by-step process for designing and developing new applications.
Writings from our team on technology, design, and business.
Get answers to the questions most frequently asked by new clients.
Learn about our company culture and defining principles.
A high level overview of FullStack Labs, who we are, and what we do.
A JavaScript framework that allows rapid development of native Android and IOS apps.
A JavaScript framework maintained by Facebook that's ideal for building complex, modern user interfaces within single page web apps.
A server side programming language known for its ease of use and speed of development.
A lightweight and efficient backend javascript framework for web apps.
An interpreted high-level programming language great for general purpose programming.
A JavaScript framework maintained by Google that addresses many of the challenges encountered when building single-page apps.
A JavaScript framework that allows developers to build large, complex, scalable single-page web applications.
A progressive JavaScript framework known for its approachability, versatility, and performance.
A progressive JavaScript framework known for its approachability, versatility, and performance.
A progressive JavaScript framework known for its approachability, versatility, and performance.
A progressive JavaScript framework known for its approachability, versatility, and performance.
A progressive JavaScript framework known for its approachability, versatility, and performance.
A progressive JavaScript framework known for its approachability, versatility, and performance.
A progressive JavaScript framework known for its approachability, versatility, and performance.
View a sampling of our work implemented using a variety of our favorite technologies.
View examples of the process we use to build custom software solutions for our clients.
View projects implemented using this javascript framework ideal for building complex, modern user interfaces within single page web apps.
View projects implemented using this framework that allows rapid development of native Android and IOS apps.
View projects implemented using this backend javascript framework for web apps.
View projects implemented using this high-level programming language great for general purpose programming.
View projects implemented using this server side programming language known for its ease of use and speed of development.
We have vast experience crafting healthcare software development solutions, including UI/UX Design, Application Development, Legacy Healthcare Systems, and Team Augmentation. Our development services help the healthcare industry by enhancing accessibility, productivity, portability, and scalability.
We offer a range of custom software development solutions for education companies of all sizes. We're experts in Education Software Development and specialists in enhancing the learning experience across web, mobile, and conversational UI.
We're experts in developing Custom Software Solutions for the Logistics Industry. Our work offered a whole new and more efficient way for Logistics companies to manage their crucial operations.
We partner with various construction industry organizations to build custom software development solutions. Our Construction Software Development Services allow construction companies to manage projects, resources, and documentation.
We have vast experience crafting healthcare software development solutions, including UI/UX Design, Application Development, Legacy Healthcare Systems, and Team Augmentation. Our development services help the healthcare industry by enhancing accessibility, productivity, portability, and scalability.
We offer a range of custom software development solutions for education companies of all sizes. We're experts in Education Software Development and specialists in enhancing the learning experience across web, mobile, and conversational UI.
We're experts in developing Custom Software Solutions for the Logistics Industry. Our work offered a whole new and more efficient way for Logistics companies to manage their crucial operations.
We partner with various construction industry organizations to build custom software development solutions. Our Construction Software Development Services allow construction companies to manage projects, resources, and documentation.
Learn more about our current job openings and benefits of working at FSL.
Detailed reviews and feedback from past and current clients.
Get to know the Management Team behind FullStack Labs.
Our step-by-step process for designing and developing new applications.
Writings from our team on technology, design, and business.
Get answers to the questions most frequently asked by new clients.
Learn about our company culture and defining principles.
A high level overview of FullStack Labs, who we are, and what we do.
A JavaScript framework that allows rapid development of native Android and IOS apps.
A JavaScript framework maintained by Facebook that's ideal for building complex, modern user interfaces within single page web apps.
A server side programming language known for its ease of use and speed of development.
A lightweight and efficient backend javascript framework for web apps.
An interpreted high-level programming language great for general purpose programming.
A JavaScript framework maintained by Google that addresses many of the challenges encountered when building single-page apps.
A JavaScript framework that allows developers to build large, complex, scalable single-page web applications.
A progressive JavaScript framework known for its approachability, versatility, and performance.
A dynamic programming language used in all sorts of web and mobile applications.
A cross-platform programming language designed to run robust applications on any device.
A UI toolkit used to build natively compiled applications from a single codebase.
A functional programming language that’s ideal for scalability, maintainability, and reliability.
A Customer Relationship Management (CRM) platform that seamlessly integrates with your business operations.
A high-performance programming language that makes it easy to build simple, reliable, and efficient software.
View a sampling of our work implemented using a variety of our favorite technologies.
View examples of the process we use to build custom software solutions for our clients.
View projects implemented using this javascript framework ideal for building complex, modern user interfaces within single page web apps.
View projects implemented using this framework that allows rapid development of native Android and IOS apps.
View projects implemented using this backend javascript framework for web apps.
View projects implemented using this high-level programming language great for general purpose programming.
View projects implemented using this server side programming language known for its ease of use and speed of development.
Welcome back to the third part of my six-part guide for Angular developers looking to learn React. Over the course of the series, we will rebuild Angular’s starter app example in React, covering each section of the Angular Starter docs in a separate article.
In part two, we learned how to leverage the React Router Dom library to implement navigation in React. This article will cover the use of Redux, one of the most popular state management libraries for React.
Let's start by reviewing the features we have implemented so far. At this point, the user can see the product catalog, click on the product name, and navigate to the product details page. In this tutorial, we will expand the app by implementing the following:
The starter kit for the app can be found here.
Data management refers to the process of storing and propagating data throughout the application. In React, state can be managed at the component level and passed down to sub components. In Angular, this can be done with a simple variable and the use of the @input and @output system to propagate the data. For small applications, this internal and simple state management might be enough, but most apps require a more robust data management system.
Modern React apps use hooks to manage the state. Take a look at the “useReducer” and “useState” hooks here.
Angular provides such a system with the use of services, which is a flexible way to share and store information. Services allow information to be injected in every component using the Angular injection system. To replicate this in React, we will need something more powerful than the internal state system provided. Although there are numerous data management solutions in React, most apps use Redux.
To get started we will need to install two libraries: redux and react-redux.
Before we implement Redux, let’s improve the organization of our app:
-- CODE language-jsx keep-markup --
import TopBar from './components/TopBar';
import ProductList from './components/ProductList';
import ProductDetails from './components/ProductDetails';
Update the product.js path in ProductAlerts.js, ProductDetails.js, and ProductList.js
-- CODE language-jsx keep-markup --
import {products} from '../products';
Refresh the page, and after the update, the scaffolding of the app should look like:
The concepts of Angular services correlate nicely with concepts within Redux. To get a better idea of why, let’s start by creating the initial state of the application that will store our items:
-- CODE language-jsx keep-markup --
const initialState = {
items: [],
};
As you can see, the initial state is a regular Javascript object that will store our items.
Next we need to define the actions a user can take on the items in the cart. For now we will let them add an item to the cart and clear the cart completely. The first step is creating a name for these actions in a file that we can reference elsewhere.
-- CODE language-jsx keep-markup --
const CartTypes = {
ADD_TO_CART: 'ADD_TO_CART',
CLEAR_CART: 'CLEAR_CART',
};
exportdefault CartTypes;
These names are self-explanatory: CartTypes.ADD_TO_CART will allow us to add a new item and CartTypes.CLEAR_CART will clear the array.
Next, we need to define the actions themselves. In Redux, an action is a function that returns an object that includes a type and a payload. Let’s create the action:
-- CODE language-jsx keep-markup --
import types from '../action-types/cart';
const axios = require('axios');
exportconst addToCart = product => {
return {
type: types.ADD_TO_CART,
product
};
};
exportconst clearCart = () => {
return {
type: types.CLEAR_CART,
}
};
Next up we need to create the reducer. Reducers are functions that return a new state of the application when an action is dispatched. How to modify the store is determined by which action-type was dispatched. You could see this as the new state generator.
-- CODE language-jsx keep-markup --
import types from '../action-types/cart';
const initialState = {
items: [],
shippingPrices: [],
shippingPricesLoading: false
};
exportdefaultfunction(state = initialState, action) {
switch (action.type) {
case types.ADD_TO_CART: {
const { product } = action;
const { items } = state;
window.alert('Your product has been added to the cart!');
return {
...state,
items: [...items, product]
};
}
case types.CLEAR_CART: {
return {
...state,
items: []
};
}
default:
return state;
}
};
If multiple files use the same strings, creating a map is a good practice.
Now that we’ve setup a redux store, we need to integrate it into the app:
-- CODE language-jsx keep-markup --
import { createStore, combineReducers, applyMiddleware, compose } from 'redux';
import { Provider } from 'react-redux';
import ReduxThunk from 'redux-thunk';
const rootReducer = combineReducers({
cart: cartReducer,
});
const logger = store => {
return next => {
return action => {
console.log('[MiddleWare] Dispatching', action);
const result = next(action);
console.log('[MiddleWare] next state', store.getState());
return result;
};
};
};
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
/* You can apply multiple middleware separated by , */
const store = createStore(rootReducer, composeEnhancers(applyMiddleware(logger, ReduxThunk)));
The store will be available in the variable “store”. One way to think about the store is as Angular Services. This means:
Finally, use the <provider></provider>; component from the “react-redux” library to “provide” the store to the application. Let's see this code in action:
-- CODE language-jsx keep-markup --
import { Provider } from 'react-redux';
....
render() {
return (
<provider store="{store}"></provider>
<router></router>
<topbar></topbar>
<div classname="container"></div>
<route exact="" path="/" component="{ProductList}"></route>
<route path="/products/:productId" component="{ProductDetails}"></route>
);
}
To inject our service into each component, we need to use the connect function available in the react-redux library. Components that interact with redux are usually called Container components, while other components are called Presentational components. This separates concerns between interacting with the store and defining the UI. You can read more about this distinction here.
Let’s separate Cart and ProductDetails into containers and presentational components:
-- CODE language-jsx keep-markup --
import React from 'react';
import { connect } from 'react-redux';
import Cart from '../components/Cart';
import * as actions from '../store/actions/cart';
const Cart = props => {
const { products } = props;
return<cart products="{products}" {...props}=""></cart>
}
const mapStateToProps = state => {
return {
products: state.cart.items,
};
};
export default connect(
mapStateToProps
)(Cart);
Above we are explicitly extracting the products from the props, but most of the times the containers component will propagate the props with the following approach:
-- CODE language-jsx keep-markup --
return<cart {...props}=""></cart>
The mapStateToProps function merges the props of the component with the data present in the store. All this setup will allow the view component to access the values of the store and react to any changes.
To interact with the store, we need to provide a second parameter to the connect function. Let’s use the DetailsComponent container as an example:
-- CODE language-jsx keep-markup --
import React from 'react';
import { connect } from 'react-redux';
import ProductDetails from '../components/ProductDetails';
import * as actions from '../store/actions/cart';
const ProductDetails = props => {
const { productId, addToCart } = props;
return<productdetails productid="{productId}" addtocart="{addToCart}" {...props}=""></productdetails>
}
const mapStateToProps = state => {
return { items: state.cart.items,
};
};
const mapDispatchToProps = dispatch => {
return {
addToCart: product => dispatch(actions.addToCart(product)),
};
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(ProductDetails);
The mapStateToProps function returns an object of methods that interact directly with the store. These actions are available directly in the props of the view component using the connection created in the container component. This means that when executing the addToCart function into the ProductDetails component, redux will generate the new state and inform all the components.
Now let’s update the components associated with each Route to point to the new Container components.
-- CODE language-jsx keep-markup --
import ProductDetails from './containers/ProductDetails';
import Cart from './containers/Cart';
render() {
return (
<provider store="{store}"></provider>
<router></router>
<topbar></topbar>
<div classname="container"></div>
<route exact="" path="/" component="{ProductList}"></route>
<route path="/products/:productId" component="{ProductDetails}"></route>
<route exact="" path="/checkout" component="{Cart}"></route>
);
}
With all this setup, actions are now available directly in the props of our view component. To add a new item in the cart, we should extract the action from the props and create a button that will execute that action onClick. The ProductDetails.js component should be updated as follows:
-- CODE language-jsx keep-markup --
import React from 'react';
import { products } from '../products';
import { currency } from '../utils';
const ProductDetails = ({ match, addToCart }) => {
const {
params: { productId }
} = match;
const product = products[productId];
return (
<div classname="product-deatils"></div>
<h2>Product Details</h2>
<div></div>
<h3>{product.name}</h3>
<h4>{currency(product.price)}</h4>
<p>{product.description}</p>
<button onclick="{()" ==""> addToCart(product)}>Buy</button>
);
};
exportdefault ProductDetails;
The action is extracted on:
-- CODE language-jsx keep-markup --
const ProductDetails = ({ match, addToCart }) => {
The HTML event that triggers the action is:
-- CODE language-jsx keep-markup --
<button onclick="{()" ==""> addToCart(product)}>Buy</button>
Although we’ve implemented a good amount of the Angular app in React, we’re still missing the shippings view. In the next article we will cover async actions and HTTP libraries. This might seem like a lot of boilerplate to get the functionality required in React but once you get familiar with the concepts and ideas of Redux and React, you will end up adding redux libraries to your Angular apps or creating your custom implementation of a store like service.
---
At FullStack Labs, we pride ourselves on our ability to push the capabilities of cutting-edge frameworks like React. Interested in learning more about speeding up development time on your next project? Contact us.
We’d love to learn more about your project.
Engagements start at $75,000.