This website uses cookies to ensure you get the best experience on our website.

Skip to content
LOGO
  • Company

    About IGNEK

    Learn about our story and our mission.

    Careers

    We're hiring!

    We always looking for talented peoples. Join our team!

    Blogs

    The latest industry news, updates and info.

    Case Studies

    Take a closer look at the projects we've delivered

    Webinar

    Watch our latest organized webinar

    Get in touch with our HR team

    • hr@ignek.com
    • +91 93284 95160
    • Ahmedabad, Gujarat, India – 382470
  • Services

    Enterprise Portal Development

    Custom Enterprise Portal Development for flawless Solutions

    Dedicated Development Team

    Expand Teams, Optimize Development with Our Expertise

    Back-end Development

    Empowering your digital presence with robust backend development expertise

    Front-end Development

    Crafting engaging user experiences through expert frontend development

    Digital Transformation

    Embrace digital transformation by modernizing process

    SaaS Development

    Transform your business with SaaS Innovative Solutions

    Technologies

    Liferay Services

    Development & Customization

    Theme

    Upgradation

    Migration

    Proof of Concept

    Performance Tunning

    Architecture

    Support & Maintenance

    E-commerce

    Expert Advice

    React Services

    Enterprise Development

    Custom Application

    Single Page Application

    Architecture

    API Integration

    Migration

    Consulting

    Maintenance & Support

    Spring Boot Services

    Web Service

    MVC Web Development

    API Integration

    Security

    Migration

    Microservices

    Support & Maintenance

    AEM Services

    Consulting Service

    Site Development

    Migration & Upgradation

    Integration

    Maintenance & Support

    Custom Solutions

    Content Management

    Team Augementation

  • Solution

    Ready for digital excellence

    In our rapidly evolving world, businesses are always on the lookout for fresh ways to improve their operations and connect with their audiences.

    Contact US

    Solutions

    SaaS : Software As A Service

    Transforming industries through cutting edge SaaS solutions.

    Customer Portal : Boost Business Productivity

    Streamline operations and enhance productivity with our Customer Portal solution.

    Liferay Based Intranet Portal

    Internal portal for company communication, collaboration and resources

    Integration

    Matomo Integration with Liferay

    Integrate Matomo to enable user interactions seamlessly.

    Microsoft Teams integration with Liferay

    Integrate to enable seamless collaboration, messaging within your portal.

    Jira Integration With Liferay

    Optimizes business operations by integrating with Jira.

  • Hire Us

    Liferay

    Get expert Liferay developers for seamless portal solutions.

    React JS

    Get expert ReactJS developers for dynamic web solutions.

    Web Developer

    Get custom web solutions from IGNEK's expert developers.

    Spring Boot

    Get top-notch Spring Boot developers for your project success!

    Healthcare

    Get top Healthcare Developers for cutting-edge medical software.

    MERN Stack

    Get expert MERN developers from IGNEK for custom, innovative project solutions.

    Why Hire Developers From IGNEK ?

    • Certified Developer
    • Transparent Communication
    • Flexible Hiring Modals
    • Fully Signed NDA
    • Cost Effective
    • Easy Exit Policy

    Get in touch with our Sales team

    • sales@ignek.com
    • +91 6351576580
    • info@ignek.com
    • Ahmedabad, Gujarat, India – 382470
SCHEDULE CALL
  • COMPANY
    • About
    • Case Studies
    • Blogs
    • Career
    • Webinar
  • SERVICES
    • Enterprise Portal Development
    • Dedicated Development Team
    • Back-end Development
    • Front-end Development
    • Digital Transformation
    • SaaS Development
  • SOLUTION
    • Customer Portal:  Boost Business Productivity
    • SaaS : Software as a Service
    • Liferay Based Employee Intranet Portal
  • TECHNOLOGY
    • Liferay Services
      • Liferay Development and Customization
      • Liferay Theme Development Service
      • Liferay DXP 7.4 Upgrade
      • Liferay Migration
      • Liferay Proof Of Concept
      • Liferay Performance Tuning
      • Liferay Architecture Design Service
      • Liferay Support And Maintenance Service
      • Liferay Ecommerce Development
      • Liferay Expert Advice
    • ReactJS Services
      • ReactJS Enterprise Application Development
      • ReactJS Custom Application Development
      • ReactJS Single Page Application Development (SPA)
      • ReactJS Applications Architecture
      • ReactJS API Integration
      • ReactJS Migration
      • ReactJS Consulting
      • ReactJS Maintenance and Support
    • Spring Boot Services
      • Spring Boot Web Development Service
      • Spring MVC Web Development
      • Spring Boot API Integration Service
      • Spring Boot Security
      • Spring Boot Migration Service
      • Spring Boot Microservices
      • Spring Boot Support & Maintenance Service
    • AEM Development Services
      • AEM Consulting Services
      • AEM Site Development
      • AEM Migration & Upgradation
      • AEM Integration Services
      • AEM Maintenance & Support
      • AEM Content Management
      • Custom AEM Solutions
      • AEM Team Augmentation
  • INTEGRATION
  • HIRE US
    • Hire Liferay Developer
    • Hire ReactJS Developer
    • Hire Spring Boot Developer
    • Hire Healthcare Developer
    • Hire Web Developer
    • Hire MERN Stack Developer
  • CONTACT US
  • Company

    About IGNEK

    Careers

    We're hiring!

    Blogs

    Case Studies

    Webinar

    Get in touch with our HR team

    • hr@ignek.com
    • +91 93284 95160
    • Ahmedabad, Gujarat, India – 382470
  • Services

    Enterprise Portal Development

    Dedicated Development Team

    Back-end Development

    Front-end Development

    Digital Transformation

    SaaS Development

    Technologies

    Liferay Liferay Services
    • Development & Customization
    • Theme
    • Upgradation
    • Migration
    • Proof of Concept
    • Performance Tuning
    • Architecture
    • Support & Maintenance
    • E-commerce
    • Expert Advice
    React React Services
    • Enterprise Development
    • Custom Application
    • Single Page Application
    • Architecture
    • API Integration
    • Migration
    • Consulting
    • Maintenance & Support
    Spring Boot Spring Boot Services
    • Web Service
    • MVC Web Development
    • API Integration
    • Security
    • Migration
    • Microservices
    • Support & Maintenance
    AEM AEM Services
    • Consulting Service
    • Site Development
    • Migration & Upgradation
    • Integration
    • Maintenance & Support
    • Custom Solutions
    • Content Management
    • Team Augmentation
  • Solution

    Ready for digital excellence

    In our rapidly evolving world, businesses are always on the lookout for fresh ways to improve their operations and connect with their audiences.

    Contact US

    Solutions

    SaaS : Software As A Service

    Customer Portal : Boost Business Productivity

    Liferay Based Intranet Portal

    Integration

    Matomo Integration with Liferay

    Microsoft Teams integration with Liferay

    Jira Integration With Liferay

  • Hire Us

    Liferay

    React JS

    Web Developer

    Spring Boot

    Healthcare

    MERN Stack

    Why Hire Developers From IGNEK ?

    • Certified Developer
    • Transparent Communication
    • Flexible Hiring Modals
    • Fully Signed NDA
    • Cost Effective
    • Easy Exit Policy

    Get in touch with our Sales team

    • sales@ignek.com
    • +91 6351576580
    • IGNEK
    • Ahmedabad, Gujarat, India – 382470
  • SCHEDULE CALL

Simplifying Global State in React with useContext and useReducer

  • ReactJS
  • August 30, 2024

Share On :

Introduction 

The Context API in React allows sharing state across the entire app without prop drilling. useReducer handles complex state logic with a reducer function. Together, they offer a powerful way to manage global state predictably, reduce boilerplate code, and improve code organization. Additionally, they enhance performance by preventing unnecessary re-renders and make it easier to debug state changes.

Prerequisites 
  • Node.js and npm
  • React
  • Typescript
  • MUI
Diving into Context API 

The Context API offers a straightforward and effective method for sharing state throughout a React component tree. It addresses the issues of prop drilling, which can be messy and frustrating when passing props down to components.

With the Context API, you can pass props to any child component of a parent, enabling state sharing without the need to pass props through each level.

  • Provider and Consumer

The Context API has two main components:

    1. Provider
    2. Consumer

The Provider is a React component that wraps other components, while the Consumer consumes the data or state passed through the Provider. It’s important to note that the Context API is ideal for passing global data. If your use case involves global state, it’s likely a suitable choice.

Diving into useReducer :

The useReducer hook enables the management of complex state logic in React components. If you’ve used Redux before, the concept of useReducer is pretty similar to Redux. A reducer is basically a switch statement defining all the possible actions a context can perform, and only updating the part of the global state related to that action.

  • Syntax

const [state, dispatch] = useReducer(reducer, initialState)

The line const [state, dispatch] = useReducer(reducer, initialState); initializes state management using useReducer in React. Here, state holds the current state of the application, while dispatch is a function that triggers state updates by invoking the reducer function with an action, and initialState represents the initial state value for the application’s state management. It defines the starting point of the state before any actions are dispatched to update it.

  • Advantages of useReducer
    • When dealing with complex state logic that involves multiple sub-values or where the next state depends on the previous one, useReducer is typically a better choice than useState.
    • Using useReducer can also help optimize component performance by allowing you to pass the dispatch function down instead of individual callbacks, which can reduce unnecessary re-renders.
A Comprehensive Guide to Application 

This React + TypeScript application is a shopping app demonstrating the use of the Context API with useReducer for state management. By using the Context API along with useReducer, the state is efficiently shared and managed across components without the need for prop drilling. This setup showcases a clean and scalable approach to handling the global state in a React application.

By following the below steps, you can easily learn how to use context api with useReducer and also make an application where you leverage the advantages of context api.

Context API

Let’s understand the folder structure

  • There is a folder for components, where all the necessary components for the application will be created.
  • There is a folder named assets, where all the styling files, images will be stored.
  • Then, a separate state folder is created for the context and reducer .

Therefore, it is good practice to follow a proper folder structure and separate our concerns.

Navigating the Frontend Setup In React 

Let’s start the UI implementation for using React with a TypeScript template.

  1. Initializing React Application : To create a React application, you need to start by creating a project folder in your root directory. Inside the project folder, install the necessary dependencies by running the following commands.
				
					// Create react app using the following cmd

npx create-react-app state-management --template typescript
				
			
  1. Please follow the below step to make the shopping app using context api and useReducer hook for state management. In the project state-management folder, locate the App.tsx file which serves as the entry point for the project.

1) Create a separate folder for the components where you will create the necessary components.

2) In that components folder, make a file named Products.tsx and CartModal.tsx.

3) Make a separate folder named state. In that folder make a file with the  nameContext.tsx and reducer.ts.

4) Make a separate folder named assets. In that folder make another folder named images to store the images.

4) Make a separate folder named helper. In that folder make a file with the name ProductData.ts to store the dummy data for the products.

5) In this app, material ui is used for styling. Design the user interface according to your preference using raw CSS or any library of your choice.

				
					//App.tsx
//Necessary imports

function App() {
  return (
    <ShopProvider>
      <Box>
        <Products />
      </Box>
    </ShopProvider>
  );
}

export default App;
				
			
  • In the App component, the Products component is wrapped inside the ShopProvider, so all the child components will be able to use the context value.
				
					//context.tsx
//Necessary imports

interface ShopContextProps {
  total: number;
  products: IProduct[];
  addToCart: (product: IProduct) => void;
  removeFromCart: (product: IProduct) => void;
}

export const ShopContext = createContext<ShopContextProps | undefined>(undefined);

export const ShopProvider = ({ children }: { children: ReactNode }) => {
  const [state, dispatch] = useReducer(shopReducer, initialState);

  const addToCart = (product: IProduct) => {
    const updatedCart = [...state.products, product];
    updatePrice(updatedCart);
    dispatch({
      type: "ADD_TO_CART",
      payload: {
        products: updatedCart,
      },
    });
  };

  const removeFromCart = (product: IProduct) => {
    const updatedCart = state.products.filter(
      (currentProduct) => currentProduct.id !== product.id
    );
    updatePrice(updatedCart);

    dispatch({
      type: "REMOVE_FROM_CART",
      payload: {
          products: updatedCart,
      },
    });
  };

  const updatePrice = (products: IProduct[]) => {
    let total = 0;
    products.forEach((product) => (total += parseFloat(product.price.slice(1))));

    dispatch({
      type: "UPDATE_PRICE",
      payload: {
        total,
      },
    });
  };

  const value = {
    total: state.total,
    products: state.products,
    addToCart,
    removeFromCart,
  };

  return <ShopContext.Provider value={value}>{children}</ShopContext.Provider>;
};
				
			
  • The ShopProvider sets up the context for managing the shopping cart state using the useReducer hook and the shopReducer function. It provides functions addToCart and removeFromCart to modify the cart and an updatePrice function to calculate the total price. 
  • The ShopContext is created and used to pass down these values and functions to the rest of the application. The provider wraps around the application’s children components to give them access to the cart state and functions.
				
					//reducer.ts

export interface IProduct {
  id: number;
  name: string;
  description: string;
  price: string;
  image: string;
}

interface InitialState {
  total: number;
  products: IProduct[];
}

export const initialState: InitialState = {
  total: 0,
  products: [],
};

interface AddToCartAction {
  type: "ADD_TO_CART";
  payload: {
    products: IProduct[];
  };
}

interface RemoveFromCartAction {
  type: "REMOVE_FROM_CART";
  payload: {
    products: IProduct[];
  };
}

interface UpdatePriceAction {
  type: "UPDATE_PRICE";
  payload: {
    total: number;
  };
}

export type Action = AddToCartAction | RemoveFromCartAction | UpdatePriceAction;

const shopReducer = (state: InitialState, action: Action): InitialState => {
  switch (action.type) {
    case "ADD_TO_CART":
      return {
        ...state,
        products: action.payload.products,
      };
    case "REMOVE_FROM_CART":
      return {
        ...state,
        products: action.payload.products,
      };
    case "UPDATE_PRICE":
      return {
        ...state,
        total: action.payload.total,
      };
    default:
      return state;
  }
};

export default shopReducer;


				
			
  • The shopReducer function manages the state of the shopping cart in a Redux-like manner. It handles three types of actions: ADD_TO_CART, REMOVE_FROM_CART, and UPDATE_PRICE. 
  • When a product is added or removed from the cart, the corresponding action updates the products array in the state. The UPDATE_PRICE action updates the total price of the items in the cart. The initialState defines the initial structure of the state with a total of 0 and an empty products array.
				
					//Products.tsx

//Necessary imports

export interface IProductData {
  id: number;
  name: string;
  description: string;
  price: string;
  image: string;
}

const Products = () => {
  const context = useContext(ShopContext);

  if (!context) {
    throw new Error("Error");
  }

  const { products, addToCart, removeFromCart, total } = context;
  const [cartIsOpen, setCartIsOpen] = useState<boolean>(false);

  const isInCart = (product: IProductData) => {
    return products.some((cartProduct) => cartProduct.id === product.id);
  };

  const handleClick = (product: IProductData) => {
    if (isInCart(product)) {
      removeFromCart(product);
    } else {
      addToCart(product);
    }
  };

  const toggleCart = () => {
    setCartIsOpen((cartIsOpen) => !cartIsOpen);
  };

  return (
    <>
      <>
        <Box>
          <AppBar position="static">
            <Toolbar>
              <Typography>
                Shopeasy
              </Typography>
              <Button
                onClick={toggleCart}
                startIcon={<ShoppingCartRoundedIcon />}
              >
                View Cart
              </Button>
            </Toolbar>
          </AppBar>
        </Box>
        <Box>
          <Typography>
            Products
          </Typography>
          <Box>
            {ProductData.map((product) => (
                { Render Product }
                <CardActions>
                  <Button onClick={() => handleClick(product)}>
                    {isInCart(product) ? "Remove from Cart" : "Add to Cart"}
                  </Button>
                </CardActions>
              </Card>
            ))}
          </Box>
        </Box>
      </>
      <CartModal open={cartIsOpen} onClose={toggleCart} />
    </>
  );
};
export default Products;


				
			
  • The Products.tsx component displays a list of products and allows users to add or remove products from their shopping cart. It utilizes ShopContext to manage the state of the cart, including the functions addToCart and removeFromCart. 
  • The component also includes a VIEW CART button to toggle the visibility of the cart modal. 
  • Each product is displayed with its image, name, description, and price, and has a button to add or remove it from the cart.
				
					//CartModal.tsx

//Necessary imports

interface ICartModalProps {
  open: boolean;
  onClose: () => void;
}

const CartModal: React.FC<ICartModalProps> = ({ open, onClose }) => {
    const context = useContext(ShopContext);

    if (!context) {
      throw new Error("Error");
    }

    const { products, total } = context;

  const handleClose = () => {
    onClose();
  };

  return (
    <Dialog onClose={handleClose} open={open}>
      <DialogTitle>
        <Typography>
          Cart
        </Typography>
      </DialogTitle>
      <DialogContent>
        {products.length ? (
          <Box>
            <Grid>
              {products.map((product) => (
                { Render Product }
              ))}
            </Grid>
            <Divider />
            <Box>
              <Typography>Total Amount</Typography>
              <Typography>{`$${total}`}</Typography>
            </Box>
          </Box>
        ) : (
          <Typography>
            Your cart is empty!
          </Typography>
        )}

        <DialogActions>
          <Button
            onClick={handleClose}
          >
            Close
          </Button>
        </DialogActions>
      </DialogContent>
    </Dialog>
  );
};

export default CartModal;


				
			
  • Here, in the CartModal component, we are using products and total from the ShopContext and then rendering the products added to the cart in the modal.
				
					//ProductData.ts

import { IProductData } from "../components/Products";

export const ProductData: IProductData[] = [
    {
        id: 1,
        name: "Shoes",
        description: "Comfortable running shoes",
        price: "$129.00",
        image: shoes1,
      },
     // Add more dummy data 
]
				
			
  • The Product.ts stores the dummy data for the products which is used in the Products.tsx component to render the products.
Conclusion 

In conclusion, creating a React TypeScript application using the Context API and the useReducer hook effectively manages the state. This approach centralizes state management, allowing for a clear and scalable structure. The Context API provides a way to pass down the state and actions without prop drilling. The useReducer hook simplifies complex state logic, making the code more maintainable and predictable.

Output
output-1
output-2
output-3
output-4

Explore Our Services

Discover how we can help your business thrive, whether you’re running a small startup, an SME, or a large enterprise. We’re here to understand your unique needs and goals, offering the expertise and resources to support your journey to success.

Stay informed about our ReactJS services and updates by subscribing to our newsletter—just fill in the details below to subscribe.

Loading
Loading...

Related Blogs

March 27, 2024
Authentication and Authorization in React
March 27, 2024
ReactJS Performance Tuning
July 19, 2024
Simplifying State with Context API
Simplifying State with Context API
Loading...

Featured Projects Portfolios

October 6, 2023
Dynamic E-commerce Platform_for Sales, Rentals and Inventory Management
Dynamic E-commerce Platform for sales, Rentals and Inventory Management
October 4, 2023
Telemedicine Appointment & Health Record Portal
Telemedicine Appointment & Health Record Portal
October 3, 2023
Simplify Approvals and Goals With Agenda & Meeting SaaS Platform
Simplify Approvals and Goals With Agenda & Meeting SaaS Platform

Digital Solutions for Your Business with IGNEK

4.9

5.0

5.0

5.0

LOGO

Making the world a better place through constructing elegant hierarchies

COMPANY

  • About
  • Career
  • Case Study
  • Blogs

SERVICES

  • Enterprise Portal Development
  • Dedicated Development Team
  • Back-end Development
  • Front-end Development
  • Digital Transformation
  • SaaS Development

HIRE US

  • Liferay
  • Spring Boot
  • ReactJS
  • Healthcare
  • MERN Stack
  • AEM

CONTACT

  • info@ignek.com
  • info@ignek.com
SALES
  • sales@ignek.com
  • (+91) 635 157 6580
CAREER
  • hr@ignek.com
  • (+91) 932 849 5160
  • E 910-912, Ganesh Glory 11, Jagatpur Road, SG Highway, Ahmedabad, Gujarat - 382470

© 2018-2025 IGNEK, Inc. All rights reserved

Linkedin Facebook X-twitter Instagram