### Title: React CRUD Operations with Axios and React Query
### Description:
This article explores the implementation of CRUD (Create, Read, Update, Delete) operations in React applications using Axios for HTTP requests and React Query for enhanced data fetching capabilities. It provides an overview of setting up these technologies and demonstrates how to create, read, update, and delete data efficiently.
### Content:
In today's web development landscape, managing CRUD operations is a fundamental task. Whether it’s a simple blog application or a complex e-commerce platform, efficient handling of these operations can significantly enhance user experience and app functionality. This article focuses on implementing CRUD operations in React applications using Axios for making HTTP requests and React Query for improved data fetching and caching.
#### Setting Up the Project
First, let's set up our React project if you haven't already done so. We will use Create React App as our scaffolding tool.
```bash
npx create-react-app my-crud-app
cd my-crud-app
npm start
```
After setting up, install Axios and React Query:
```bash
npm install axios react-query @tanstack/react-query
```
#### Creating the Data Model
For simplicity, we'll create a fictional "Product" model. Our Product model will have properties like `id`, `name`, `price`, and `quantity`.
```jsx
// src/models/Product.js
export interface Product {
id: number;
name: string;
price: number;
quantity: number;
}
```
#### Fetching Data with React Query
React Query simplifies fetching data by providing hooks that handle the lifecycle of data fetching, caching, and updating. First, we need to define a query key to fetch products.
```jsx
// src/hooks/useProducts.ts
import { useQuery } from 'react-query';
const useProducts = () => {
return useQuery('products', async () => {
const response = await fetch('https://api.example.com/products');
return await response.json();
});
};
export default useProducts;
```
Now, let's consume this hook in our component to display the list of products.
```jsx
// src/components/ProductsList.tsx
import React from 'react';
import { useProducts } from '../hooks/useProducts';
import ProductCard from './ProductCard';
const ProductsList: React.FC = () => {
const { data, error, isLoading } = useProducts();
if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return (
<div>
{data.map((product: Product) => (
<ProductCard key={product.id} product={product} />
))}
</div>
);
};
export default ProductsList;
```
#### Creating, Reading, Updating, and Deleting Products
Let's create a form to add new products and implement CRUD operations.
```jsx
// src/components/AddProductForm.tsx
import React, { useState } from 'react';
import { useProducts } from '../hooks/useProducts';
import ProductCard from './ProductCard';
const AddProductForm: React.FC = () => {
const [product, setProduct] = useState<Product>({
id: 0,
name: '',
price: 0,
quantity: 0,
});
const { mutate } = useProducts();
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
const { id, ...rest } = product;
await mutate({ variables: { input: rest } });
setProduct({ id: 0, name: '', price: 0, quantity: 0 });
};
return (
<form onSubmit={handleSubmit}>
<input type="text" value={product.name} onChange={(e) => setProduct({ ...product, name: e.target.value })} placeholder="Name" />
<input type="number" value={product.price} onChange={(e) => setProduct({ ...product, price: parseFloat(e.target.value) })} placeholder="Price" />
<input type="number" value={product.quantity} onChange={(e) => setProduct({ ...product, quantity: parseInt(e.target.value) })} placeholder="Quantity" />
<button type="submit">Add Product</button>
</form>
);
};
```
Next, let's create a form to edit existing products.
```jsx
// src/components/EditProductForm.tsx
import React, { useState } from 'react';
import { useProducts } from '../hooks/useProducts';
import ProductCard from './ProductCard';
const EditProductForm: React.FC<{ product: Product }> = ({ product }) => {
const [newProduct, setNewProduct] = useState(product);
const { mutate } = useProducts();
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
await mutate({ variables: { id: product.id, input: newProduct } });
};
return (
<form onSubmit={handleSubmit}>
<input type="text" value={newProduct.name} onChange={(e) => setNewProduct({ ...newProduct, name: e.target.value })} placeholder="Name" />
<input type="number" value={newProduct.price} onChange={(e) => setNewProduct({ ...newProduct, price: parseFloat(e.target.value) })} placeholder="Price" />
<input type="number" value={newProduct.quantity} onChange={(e) => setNewProduct({ ...newProduct, quantity: parseInt(e.target.value) })} placeholder="Quantity" />
<button type="submit">Update Product</button>
</form>
);
};
```
Finally, let's implement the logic to delete products.
```jsx
// src/components/DeleteProductModal.tsx
import React, { useState } from 'react';
import { useProducts } from '../hooks/useProducts';
const DeleteProductModal: React.FC<{ productId: number }> = ({ productId }) => {
const { mutate } = useProducts();
const handleDelete = async () => {
await mutate({ variables: { id: productId } });
};
return (
<div className="modal">
<h2>Delete Product</h2>
<p>Are you sure you want to delete this product?</p>
<button onClick={handleDelete}>Delete</button>
</div>
);
};
```
With these components, you can now create, read, update, and delete products in your React application. The combination of Axios for making HTTP requests and React Query for efficient data management ensures that your application remains responsive and scalable.