Replacing the Context API with Redux Toolkit provides a more structured and scalable way to manage global state in React Native applications. It simplifies state logic while improving performance and maintainability.
- Centralizes application state in a single predictable store.
- Reduces unnecessary re-renders compared to multiple contexts.
- Provides built-in tools for handling actions and reducers efficiently.
- Improves debugging with powerful Redux DevTools.
Implementing Redux Toolkit in React Native
It provides a modern and efficient way to manage global application state with simplified configuration and better scalability.
Step 1: Setting Up Redux Toolkit
First, you need to install Redux Toolkit and React-Redux:
npm install @reduxjs/toolkit react-reduxStep 2: Creating the Redux Store
Create a file named store.tsx (or any name you prefer) to set up the Redux store using the configureStore method from Redux Toolkit:
// store.tsx
import { configureStore } from '@reduxjs/toolkit';
import shoppingCartReducer from './shoppingCartSlice';
export const store = configureStore({
reducer: {
shoppingCart: shoppingCartReducer,
// You can add more reducers here if needed
},
});
Step 3: Defining Slice for Shopping Cart
In Redux Toolkit, you define a 'slice' to manage state for a specific feature of your application. Let's create a slice for the shopping cart:
// shoppingCartSlice.tsx
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import { Item } from '../Types/ShoppingCart.interface'; // Adjust the import path as needed
type ShoppingCartState = Item[];
const initialState: ShoppingCartState = [];
export const shoppingCartSlice = createSlice({
name: 'shoppingCart',
initialState,
reducers: {
addItemToCart: (state, action: PayloadAction<Item>) => {
state.push(action.payload);
},
removeItemFromCart: (state, action: PayloadAction<number>) => {
return state.filter(item => item.id !== action.payload);
},
updateCartItemQuantity: (state, action: PayloadAction<{ id: number; newQuantity: number }>) => {
return state.map(item =>
item.id === action.payload.id
? { ...item, quantity: action.payload.newQuantity }
: item
);
},
},
});
export const { addItemToCart, removeItemFromCart, updateCartItemQuantity } = shoppingCartSlice.actions;
export default shoppingCartSlice.reducer;
Step 4: Integrating the Slice into the Store
Import the reducer from the shopping cart slice and include it in the store configuration:
// store.tsx
import { configureStore } from '@reduxjs/toolkit';
import shoppingCartReducer from './shoppingCartSlice';
export const store = configureStore({
reducer: {
shoppingCart: shoppingCartReducer,
// Add more reducers here if needed
},
});
Step 5: Providing the Redux Store
Wrap your application with the Provider component from react-redux and pass the Redux store:
// index.tsx or App.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { store } from './store';
import App from './App';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
Step 6: Accessing State and Dispatching Actions in Components
Modify your components to use Redux Toolkit's useSelector and useDispatch hooks to access the state and dispatch actions, respectively:
// ShoppingCartComponent.tsx
import React, { useState } from "react";
import { useSelector, useDispatch } from "react-redux";
import { addItemToCart, removeItemFromCart, updateCartItemQuantity } from "../../store/shoppingCartSlice";
import { Item } from "../../Types/ShoppingCart.interface";
import {
CartContainer,
AddItemForm,
Input,
Button,
ItemInfo,
ItemName,
ItemQuantity,
ItemContainer,
} from "./ShoppingCartStyles";
function ShoppingCart() {
const cart = useSelector((state) => state.shoppingCart);
const dispatch = useDispatch();
// State for the new item to add
const [newItem, setNewItem] = useState<Item>({
id: Math.floor(Math.random() * 1000), // Just a temporary random ID
name: "",
quantity: 0,
});
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target;
setNewItem((prevItem) => ({
...prevItem,
[name]: name === "quantity" ? parseInt(value) : value,
}));
};
const handleAddItem = () => {
dispatch(addItemToCart(newItem));
setNewItem({
id: Math.floor(Math.random() * 1000), // Generate a new temporary random ID
name: "",
quantity: 0,
});
};
return (
<CartContainer>
<AddItemForm>
<h3>Add Item to Cart:</h3>
<Input
type="text"
name="name"
placeholder="Item Name"
value={newItem.name}
onChange={handleInputChange}
/>
<Input
type="number"
name="quantity"
placeholder="Quantity"
value={newItem.quantity}
onChange={handleInputChange}
/>
<Button onClick={handleAddItem}>Add to Cart</Button>
</AddItemForm>
{cart.map((item) => (
<ItemContainer key={item.id}>
<ItemInfo>
<ItemName>{item.name}</ItemName>
<ItemQuantity>Quantity: {item.quantity}</ItemQuantity>
</ItemInfo>
<Button
onClick={() => dispatch(updateCartItemQuantity({id: item.id, newQuantity: item.quantity + 1}))}
>
+
</Button>
<Button
onClick={() => dispatch(updateCartItemQuantity({id: item.id, newQuantity: item.quantity - 1}))}
>
-
</Button>
<Button onClick={() => dispatch(removeItemFromCart(item.id))}>Remove</Button>
</ItemContainer>
))}
</CartContainer>
);
}
export default ShoppingCart;
- Uses useSelector to read the shopping cart data from the Redux Toolkit store and useDispatch to send actions.
- Allows users to add new items and update item quantities through dispatched Redux actions.
- Displays all cart items and provides buttons to increase, decrease, or remove items from the cart.