Component Structure
Music Store follows a consistent component organization pattern. Each component has its own folder with the component file inside.
Folder Structure Pattern
src/components/
├── ComponentName/
│ └── ComponentName.jsx
Component folders use PascalCase naming (e.g., NavbarGlass, CartPanel, ShinyText)
Creating a New Component
Create the component folder
Create a new folder in src/components/ with your component name:mkdir src/components/MyComponent
Create the component file
Create the JSX file with the same name:touch src/components/MyComponent/MyComponent.jsx
Add the component code
Follow the project’s component structure pattern:import { useEffect, useRef } from "react";
import gsap from "gsap";
function MyComponent() {
const componentRef = useRef(null);
useEffect(() => {
const ctx = gsap.context(() => {
// Animation code here
});
return () => ctx.revert();
}, []);
return (
<section className="py-20 px-6 bg-[#0e0e0e]">
{/* Component content */}
</section>
);
}
export default MyComponent;
Import and use the component
Import your component where needed:import MyComponent from "../components/MyComponent/MyComponent";
function App() {
return (
<div>
<MyComponent />
</div>
);
}
Real Example: Brands Component
Here’s how the Brands component is structured in the project:
const BRANDS = [
{ name: "Fender", logo: "/brands/fender.svg" },
{ name: "Gibson", logo: "/brands/gibson.svg" },
{ name: "Ibanez", logo: "/brands/ibanez.svg" },
{ name: "PRS", logo: "/brands/prs.png" },
{ name: "Yamaha", logo: "/brands/yamaha.svg" },
];
function Brands() {
return (
<section className="py-20 px-6 bg-[#0e0e0e]">
<p className="text-center text-xs tracking-[0.4em] uppercase text-white/30 mb-12">
Marcas oficiales
</p>
<div className="max-w-5xl mx-auto flex flex-wrap justify-center items-center gap-12">
{BRANDS.map((brand) => (
<div
key={brand.name}
className="group flex items-center justify-center w-32 h-16 opacity-30 hover:opacity-100 transition-opacity duration-300 cursor-pointer"
>
<img
src={brand.logo}
alt={brand.name}
className="max-h-10 w-auto object-contain"
style={{ filter: "brightness(0) invert(1)" }}
/>
</div>
))}
</div>
</section>
);
}
export default Brands;
Component Patterns
Using React Hooks
Most components in Music Store use React hooks for state and side effects:
import { useState, useEffect, useRef } from "react";
function MyComponent() {
const [isOpen, setIsOpen] = useState(false);
const elementRef = useRef(null);
useEffect(() => {
// Side effects here
}, []);
return <div ref={elementRef}>...</div>;
}
Using Context
For shared state like the shopping cart, components use React Context:
import { useCart } from "../../context/CartContext/CartContext.jsx";
function MyComponent() {
const { carrito, setCarritoAbierto } = useCart();
return (
<button onClick={() => setCarritoAbierto(true)}>
Carrito ({carrito.length})
</button>
);
}
Using React Router
For navigation and routing:
import { Link, useParams, useLocation } from "react-router-dom";
function MyComponent() {
const { id } = useParams();
const location = useLocation();
return (
<Link to="/categoria/guitarra">
Ver Guitarras
</Link>
);
}
Common Component Types
Layout Components
Components that define page structure (Navbar, Footer)
UI Components
Reusable UI elements (Buttons, Cards, Modals)
Feature Components
Business logic components (CartPanel, ProductDetail)
Effect Components
Visual effects and animations (Grainient, Squares, ShinyText)
Best Practices
- Keep components focused on a single responsibility
- Use meaningful component and variable names
- Extract reusable logic into custom hooks
- Clean up effects and animations in the return function
- Use refs for DOM manipulation and GSAP animations
File Organization
The project structure separates components from pages:
src/
├── components/ # Reusable components
│ ├── Navbar/
│ ├── Hero/
│ └── ...
├── pages/ # Page components
│ ├── Categoria.jsx
│ └── ...
├── context/ # React Context providers
└── App.jsx # Main app component