Learn how to set up a shopping cart application using Redux in Flutter, including architecture design, state management, and key implementation steps.
In this section, we will embark on an exciting journey to build a shopping cart application using Redux in Flutter. This project will serve as a practical example to understand how Redux can be utilized to manage state effectively in a Flutter application. We’ll cover everything from setting up the project to designing the architecture and implementing key features. By the end of this guide, you’ll have a solid foundation to build and expand upon a shopping cart app using Redux.
The primary goal of this project is to create a shopping cart application that allows users to interact with a list of products. The app will include the following features:
These features will provide a comprehensive understanding of how to manage state using Redux in a Flutter application.
Before diving into the code, it’s crucial to plan out the architecture of the application. A well-thought-out architecture will make the development process smoother and the code more maintainable.
The state of our application will be managed by a central AppState
class. This class will hold the list of available products and the items currently in the cart.
class AppState {
final List<Product> products;
final List<CartItem> cartItems;
AppState({required this.products, required this.cartItems});
AppState.initial()
: products = initialProductList,
cartItems = [];
}
In Redux, actions are payloads of information that send data from your application to your Redux store. We’ll define the following actions:
class AddToCartAction {
final Product product;
AddToCartAction(this.product);
}
class RemoveFromCartAction {
final Product product;
RemoveFromCartAction(this.product);
}
class UpdateQuantityAction {
final Product product;
final int quantity;
UpdateQuantityAction(this.product, this.quantity);
}
Reducers specify how the application’s state changes in response to actions sent to the store. We’ll implement reducers to handle the defined actions and update the state accordingly.
AppState appReducer(AppState state, dynamic action) {
if (action is AddToCartAction) {
return AppState(
products: state.products,
cartItems: List.from(state.cartItems)..add(CartItem(product: action.product, quantity: 1)),
);
} else if (action is RemoveFromCartAction) {
return AppState(
products: state.products,
cartItems: state.cartItems.where((item) => item.product != action.product).toList(),
);
} else if (action is UpdateQuantityAction) {
return AppState(
products: state.products,
cartItems: state.cartItems.map((item) {
if (item.product == action.product) {
return CartItem(product: item.product, quantity: action.quantity);
}
return item;
}).toList(),
);
}
return state;
}
Let’s start by setting up the Flutter project and adding the necessary dependencies.
Open your terminal and run the following command to create a new Flutter project:
flutter create shopping_cart_redux
Navigate into the project directory:
cd shopping_cart_redux
Open the pubspec.yaml
file and add the redux
and flutter_redux
packages:
dependencies:
flutter:
sdk: flutter
redux: ^5.0.0
flutter_redux: ^0.8.2
Run flutter pub get
to install the new dependencies.
A well-organized file structure is essential for maintaining a clean and scalable codebase. Here’s how we’ll structure our project:
Product
and CartItem
.Inside the lib
directory, create the following folders:
mkdir lib/actions lib/models lib/reducers lib/middleware lib/ui
Let’s implement some of the core components of our shopping cart app.
Create a Product
model in lib/models/product.dart
:
class Product {
final String id;
final String name;
final double price;
Product({required this.id, required this.name, required this.price});
}
Create a CartItem
model in lib/models/cart_item.dart
:
class CartItem {
final Product product;
final int quantity;
CartItem({required this.product, required this.quantity});
}
Define an initial list of products in lib/models/initial_products.dart
:
import 'product.dart';
final List<Product> initialProductList = [
Product(id: '1', name: 'Laptop', price: 999.99),
Product(id: '2', name: 'Smartphone', price: 499.99),
Product(id: '3', name: 'Headphones', price: 199.99),
];
In lib/main.dart
, set up the Redux store and connect it to the Flutter app:
import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:redux/redux.dart';
import 'models/product.dart';
import 'models/cart_item.dart';
import 'reducers/app_reducer.dart';
void main() {
final store = Store<AppState>(
appReducer,
initialState: AppState.initial(),
);
runApp(MyApp(store: store));
}
class MyApp extends StatelessWidget {
final Store<AppState> store;
MyApp({required this.store});
@override
Widget build(BuildContext context) {
return StoreProvider<AppState>(
store: store,
child: MaterialApp(
title: 'Shopping Cart Redux',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: ProductListScreen(),
),
);
}
}
This comprehensive guide has walked you through setting up a shopping cart application using Redux in Flutter. We’ve covered the architecture, state management, and key implementation steps. By following these guidelines, you can build a robust and scalable shopping cart app. Remember, the key to successful app development lies in thorough planning, clear architecture, and effective state management.
To deepen your understanding of Redux and Flutter, consider exploring the following resources: