React Reduce Vs Jotai

  •        0
  

We aggregate and tag open source projects. We have collections of more than one million projects. Check out the projects section.



While developing web applications, we built many components and having a data model across the application wide model will be difficult. We need common store management to update and get information across all the components. In React based Web UI, redux is the official centralized state management to be used, which is internally wired as state changes to the component. There are other alternatives to redux which are light-weight and simple to use. One among them is Jotai, a minimalistic API for state management. In this blog, we will take one of the redux examples given in the redux site and do the same in Jotai for deeper understanding.

Shopping Cart Example (Redux):

Redux is a pattern and library for managing and updating application state, using events called "actions". createStore helps to create a centralized store for managing the data model and applying actions or using selectors by the component. It also uses middleware to create logger statements. Store dispatch the actions or rules which takes the state and action and returns the state for the components to use. 

const store = createStore (
    reducer,
    applyMiddleware(...middleware)
 )
store.dispatch(getAllProducts())

Initial dispatch loads all the products to the state which is initiated by getAllProducts dispatch call. It internally triggers the RECEIVE_PRODUCTS action, which will load the products to the state. This action loads the products to the state.

const byId = (state = {}, action) => {
	  switch (action.type) {
		case RECEIVE_PRODUCTS:
		  return {
		...state,
		...action.products.reduce((obj, product) => {
		  obj[product.id] = product
		  return obj
		}, {})
      }

Shopping cart basically list the products so users can add to cart. Next major action will be ADD_TO_CART which will impact the products inventory and cart. In cart, it will add the item.

const addedIds = (state = initialState.addedIds, action) => {
	  switch (action.type) {
		case ADD_TO_CART:
		  if (state.indexOf(action.productId) !== -1) {
		       return state
		  }
		  return [ ...state, action.productId ]
          

and increment the quantity by 1 to the cart. 

const quantityById = (state = initialState.quantityById, action) => {
	  switch (action.type) {
		case ADD_TO_CART:
		  const { productId } = action
		  return {
                       ...state,
		       [productId]: (state[productId] || 0) + 1
		  }

Likewise product inventory to be reduced because of the ADD_TO_CART actions.

const products = (state, action) => {
	  switch (action.type) {
		case ADD_TO_CART:
		  return {
		...state,
		inventory: state.inventory - 1
	 }

Cart will hold all the product selection and by clicking on checkout, it takes all the products out. It is initiated by CHECKOUT_REQUEST actions which will initialize the cart.

export const checkout = products => (dispatch, getState) => {
	  const { cart } = getState()

	  dispatch({
		type: types.CHECKOUT_REQUEST
	  })
	  shop.buyProducts(products, () => {
		dispatch({
		  type: types.CHECKOUT_SUCCESS,
		  cart
		})

	const cart = (state = initialState, action) => {
	  switch (action.type) {
		case CHECKOUT_REQUEST:
		  return initialState

Redux helps you deal with shared state management, but like any tool, it has trade-offs. There are more concepts to learn, and more code to write. To maintain the list of products and add the items to cart requires 4 to 5 action types, 10 reducers and wire those actions and selectors to the react component. State should be managed by ids and not passing the whole object, so memory will not be bloated. Dispatching many actions will cause multiple updates and re-renders we can control by batching the actions react package. There are many other recommendations that need to be taken care to have optimized performance of the app.

To solve the problems, we are suggesting Jotai which represents the state as atom. React context is a top down solution which requires memoization of the state to avoid re-renders. Jotai is a bottom-up approach when there is change in atom, it will re-render only the component dependent on the atoms.

We can create the atoms very easily using atom and enclosed with the values (it can be Number, String, or Object), which creates the config.

import { atom } from 'jotai'

const priceAtom = atom(10)
const messageAtom = atom('hello')
const productAtom = atom({ id: 12, name: 'good stuff' })

Now the atom values can be used inside the component using useAtom to get the state. The useAtom function returns the atom value and an update function as a tuple, just like React's useState. It takes an atom config created with atom().

const [value, updateValue] = useAtom(anAtom)

Now the shopping cart example requires basically two atoms one is the product atom and the other is cart atom. Product atom will be initialized with the list of products at the start of the app. Cart atom will have an empty selection of the products. 

export const productAtom = atom(Product);
export const cartAtom = atom([]);

As a product is available like a state variable in the product component, we can iterate the product and create those items in the UI. A product is an object which holds the price and quantity information also. So those are used to display for each product. 

<h3>Products</h3>
     {product &&
 	   product.map((val) => (
	  <div key={val.id}>
		{val.title} - ${val.price} {val.quantity !== 0 ? `x ${val.quantity}` : ""}
		<br />
		<button disabled={val.quantity === 0} onClick={() => handleClick(val)}>
		  {val.quantity !== 0 ? "Add to Cart" : "Sold Out"}
		</button>
		<br /> <br />
	  </div>
	))}
</>

Now click on the item, it will add the item to cart. In the handleClick method, it takes the product and then checks the item already present in the cart. If the item is found, it will increment the cart item quantity or add a new item to the cart and put back to the atom. Once atom state changes, it propagates to the cart components which use the cart atom. 

const [cart, setCart] = useAtom(cartAtom);
     const handleClick = (val) => {
	  const data = product;
	  console.log("item to add ", val);
	  let tempCart = [...cart];
	  console.log("before cart add", tempCart);

	  let isFound = false;
	  tempCart.forEach(item => {
	  if (item.id === val.id) {
		  item.quantity += 1;
		  isFound = true;
           }
	  });

	  if (!isFound) {
	       tempCart.push({id: val.id, title: val.title, price: val.price, quantity: 1});
          }

	  setCart(tempCart);
	  console.log("after cart add", cart);

In the cart container, the cart atom used to display the cart items with the quantity and price. Initially the cart will be empty, that time it will show the "Please add items to the cart". When the items are added in the products component, the cart atom is updated which will initiate the re-render in the cart container. 

	const CartContainer = () => {
	  const [ cart, setCart ] = useAtom(cartAtom);
	.....
	{cart ?
		cart.map((val) => (
		  <div key={val.id}>
			{val.quantity !== 0 ? (
			  <>
				{val.title} - ${val.price} x {val.quantity}
			  </>
			) : null}
		  </div>
		)) : "Please add items to the cart"}
	<br />

Likewise we will update the product state by decrementing the quantity and updating the product atom in the product's container. 

data[val.id].quantity = data[val.id].quantity - 1;
setProduct([...data]);
console.log('pushed item', cart);

The total amount is a kind of selector on the items available in the cart. So we can use derived atoms which calculate the items price based on the quantity and returns the totalPrice. get read function which will loop the items and calculate the total price. The total price can be taken through the useatom and displayed in the UI.

const totalAtom = atom((get) => {
	  let totalPrice = 0;
	  get(cartAtom).forEach(item => {
		totalPrice += (item.price * item.quantity);
	  })
	  return totalPrice;
	});

In the cart container, the useAtom uses the totalAtom and that totalPrice is displayed next to the cart items. 

const [ totalPrice ] = useAtom(totalAtom);

{ totalPrice > 0 ? <>Total: ${totalPrice}</>: null}

Likewise checkout will clear the items in the cart atom which will be automatically updated in the cart component. 

const CartContainer = () => {
	  const [ cart, setCart ] = useAtom(cartAtom);
	  const doCheckout = () => {
		console.log("total price ", totalPrice);
		setCart([]);
	  };

Heap memory usage has been recorded initially and adding the item to cart and then recorded the memory snapshot. This same exercise has been done both in jotai and react-redux respectively. Initial state of memory is less and after adding items to the cart also less as react redux memory kept increasing more than 3.7mb. Below First screenshot is of Jotai heap memory and the second one is of the heap memory snapshot of the react redux

References:

GitHub Project Link : https://github.com/devgroves/reduxexampleinjotai


   

DevGroves Technologies is a IT consulting and services start-up company which is predominately to web technologies catering to static website, workflow based CRM websites, e-commerce websites and reporting websites tailoring to the customer needs. We also support open source community by writing blogs about how, why and where it need to be used for.

Subscribe to our newsletter.

We will send mail once in a week about latest updates on open source tools and technologies. subscribe our newsletter



Related Articles

Build Consulting Website using Next.js

  • react nextjs website-development ssr

One of the popular web framework for building Single page application (SPA) or static site is React library. Application built with React packages will be rendered completely on the client side browser. If you want to reduce the load on client side browser, we need to pre-render the pages in server (Serer side rendering) and serve it to the client. So the client loads the page like simple html page. Also if the pages are rendered from server then search engine will be able to fetch and extract the pages. To do SSR for React, the best abstraction framework is Next.js. In this blog, we will explain how to build a simple consulting website using NextJS.

Read More


React Media Lightbox

  • lightbox gallery react audio video

Lightbox is a popular and widely used concept for showing the gallery of media files. It is a very impressive approach for the end user to glance through media files. Media files like audio or video will load the html audio or video controls.

Read More


React Patent Clause Licensing issue. Is it something to worry?

  • react react-license facebook

React libraries from Facebook is one of the most used UI libraries. It is competitive to AngularJS. There are many open source UI components or frameworks available but mostly people narrow down to two choices Angular / React. Recently Facebook has updated React license and added a patent clause which makes companies to worry and rethink whether to use React or not.

Read More


Build Simple Ecommerce site using React and Jotai

  • ecommerce react jotai

Retail Ecommerce website can be created quickly with React. It can be created using React, Bootstrap, React DOM and Jotai. Data flow within the commerce site is done using Jotai in a light-weight manner. The main workflow of showing all the items in the gallery to user and user adding to the cart will be done as part of this blog.

Read More


React Window - Optimized way to display large list

  • react react-window large-list

In Web development, there will be always a need to display content in a large list. Rendering a large list will slow down the web page load and increase the First Contentful Paint(FCP). Usually large lists are displayed in a paginated grid where user has to move around pages by clicking next. It will be good user experience, if the same page provides data of large list as and when we scroll.

Read More



React JS Developer Salary Overview

  • reactjs javascript salary

These days, web development is a need for any business - it attracts huge investments and can kick-start businesses. As for the tools mainly used for development, JavaScript is riding the wave right now. StackOverflow has been naming it the most popular programming language for six years straight. React, as one of the most popular JS libraries is also the first choice for interface developers. It offers some of the best web development tools for mobile and single-page applications.

Read More


React Media LightBox - Part 2

  • react lightbox gallery media

In this blog, we will bring the essential features zoom control, download, fullscreen to enhance the view experience of the media items. Lightbox components provide options for captioning the media items as well. Brought all the features only with material design and there are no dependencies required for the functionalities of the media lightbox.

Read More


Scene.js - Library to Create Timeline-Based Animation

  • scenejs css timeline javascript animation motion

Scene.js is a JavaScript timeline-based animation library for creating animation websites. As an animated timeline library, it allows you to create a chronological order of movements and positions of objects.

Read More


Glific - Open Source Two Way Communication Platform for Social Sector Organizations

  • glific elixir communication architecture social-sector

Glific is an open source two way communication platform with primary focus on helping social sector organizations to interact with millions of beneficiaries concurrently through automated messages with rich media content and manual intervention wherever required. With Glific one can design flows to automate conversations, see how each of the beneficiaries is interacting with the bot and measure engagement.

Read More


Data Fetching and Form Building using NextJS

  • nextjs data-fetching form-handling

Next.js is one of the easy-to-learn frameworks for server-side pre-render pages for client-side web applications. In this blog, we will see how we can fetch data from API and make it pre-render pages. Also, let's see how forms work in Next.js and collect the data without maintaining the database.

Read More


Exonum Blockchain Framework by the Bitfury Group

  • blockchain bitcoin hyperledger blockchain-framework

Exonum is an extensible open source blockchain framework for building private blockchains which offers outstanding performance, data security, as well as fault tolerance. The framework does not include any business logic, instead, you can develop and add the services that meet your specific needs. Exonum can be used to build various solutions from a document registry to a DevOps facilitation system.

Read More


An introduction to web cache proxy server - nuster

  • web-cache proxy-server load-balancer

Nuster is a simple yet powerful web caching proxy server based on HAProxy. It is 100% compatible with HAProxy, and takes full advantage of the ACL functionality of HAProxy to provide fine-grained caching policy based on the content of request, response or server status. This article gives an overview of nuster - web cache proxy server, its installation and few examples of how to use it.

Read More


Electron JS- Native capabilities

  • electronjs electron desktop-app

Electron is an open source library to build native applications which also works as cross-platform desktop applications. It provision operating system functionalities with help of node integration. In this article, we will go through how to access the Operating System variables, Inter system communication, System dialog, Access files, folders also their statistics.

Read More


Top 3 color quantization algorithms

  • color-optimization color-quantization algorithm

I have been writing on the desktop image processing application. At the version 1.0, I use the octree color quantization algorithm to reduce image to 256 colors, which is highly memory efficient with each pixel assigned the color at the center of the octree bin in which it falls. On the other hand, generates the palette using the distribution of colors in the image, but it does not consider the frequency of color. This means that if an image is composed of similar colors overall but has many different low-frequency colors or noise, octree's results can be very poor.

Read More


Appserver.io – The First Multithreaded Application Server for PHP written in PHP

  • appserver application-server php

What if you could reliably run PHP without Nginx or Apache, but also without relying on its internal server? What if you could do async operations in PHP with true multi threading, fully taking advantage of multi core processors without hacks or a jungle of callbacks? What if you had drag and drop installation support for your PHAR packaged web apps in an environment identical to its production counterpart? Welcome to appserver.io – the worlds first open source application server for PHP.

Read More


JHipster - Generate simple web application code using Spring Boot and Angular

  • jhipster spring-boot angular web-application

JHipster is one of the full-stack web app development platform to generate, develop and deploy. It provides the front end technologies options of React, Angular, Vue mixed with bootstrap and font awesome icons. Last released version is JHipster 6.0.1. It is licensed under Apache 2 license.

Read More


Generate PDF from Javascript using jsPDF

  • pdf jspdf javascript

We show lot of data in our web applications, it will be awesome if we quickly download specific part of PDF rather than printing it. It will be easy to share for different stakeholders and also for focused meetings. In web application development, download to PDF means, we need to develop backend api specifically and then link it in frontend which takes longer development cylce. Instead it would be really great, if there is way to download what we see in the user interface quickly with few lines of Javascript, similar to export options in word processing application.

Read More


Google Open Source Pledge

  • google open-source patent

Open Source is the way to innovate and users using it should have complete freedom. Google has came forward to declare couple of its patents on Map Reduce under Open Patent Non-Assertion Pledge (OPN Pledge). There are multiple variants of open source license and using that means the product is completely free. Why OPN Pledge is required?

Read More


Lucene / Solr as NoSQL database

  • lucene solr no-sql nosql document-store

Lucene and Solr are most popular and widely used search engine. It indexes the content and delivers the search result faster. It has all capabilities of NoSQL database. This article describes about its pros and cons.

Read More


Introduction to Apache Cassandra

  • cassandra database nosql

Apache Cassandra was designed by Facebook and was open-sourced in July 2008. It is regarded as perfect choice when the users demand scalability and high availability without any impact towards performance. Apache Cassandra is highly scalable, high-performance distributed database designed to handle large voluminous amounts of data across many commodity servers with no failure.

Read More







We have large collection of open source products. Follow the tags from Tag Cloud >>


Open source products are scattered around the web. Please provide information about the open source projects you own / you use. Add Projects.