Estructura de un Proyecto

Una organización clara de carpetas y archivos es clave para mantener un proyecto escalable y fácil de entender.

Disposición Típica de Carpetas

my-app/
├── node_modules/      # Dependencias que instala npm o yarn
├── public/            # Archivos estáticos (imágenes, favicon, etc.)
├── src/               # 📌 Aquí va TODO tu código React
│   ├── App.jsx        # Componente principal de tu aplicación
│   ├── main.jsx       # Punto de entrada donde se renderiza <App />
│   ├── components/    # Carpeta donde guardas tus componentes
│   │   ├── Header.jsx
│   │   └── Card.jsx
│   └── styles/        # Archivos CSS o Tailwind
│
├── package.json       # Configuración del proyecto y dependencias
└── vite.config.js     # Configuración si usas Vite

Componentes Funcionales

Son funciones de JavaScript que devuelven elementos de React (usualmente escritos en JSX). Son la forma moderna y estándar de escribir componentes.

Componente Básico

// Un componente es solo una función que retorna JSX.
const Saludo = () => {
  return <h1>Hola Mundo desde un Componente</h1>;
};

// Se puede simplificar si solo retorna una línea.
const Boton = () => <button>Haz clic</button>;

Uso de Props

// Las props son un objeto que recibe el componente.
const SaludoPersonalizado = (props) => {
  return <h1>Hola, {props.nombre}</h1>;
};

// Usando desestructuración (más común).
const SaludoElegante = ({ nombre }) => {
    return <h1>Hola, {nombre}</h1>;
}

// Uso: <SaludoElegante nombre="Samuel" />

Manejo de Eventos

React puede responder a interacciones del usuario como clics, cambios en inputs y más, usando manejadores de eventos como `onClick` y `onChange`.

Ejemplo de Evento `onChange`

Hola, ...

import { useState } from 'react';

function NameInput() {
  const [nombre, setNombre] = useState('');

  const handleInputChange = (event) => {
    setNombre(event.target.value);
  };

  return (
    <div>
      <input type="text" value={nombre} onChange={handleInputChange} />
      <p>Hola, {nombre}</p>
    </div>
  );
}

Renderizado Condicional

Muestra u oculta elementos de la interfaz según el estado de tu aplicación. Es fundamental para crear UIs dinámicas.

Ejemplo Interactivo

¡Bienvenido! Has iniciado sesión.

Operador Ternario

{ isLoggedIn ? <Welcome /> : <Login /> }

Operador Lógico `&&`

{ isLoggedIn && <Welcome /> }

Manejo de Listas y Keys

Para mostrar una colección de elementos, se utiliza el método `.map()`. La prop `key` es crucial para que React identifique cada elemento de forma única y optimice su renderizado.

Lista de Tareas Interactiva

Añadir Nueva Tarea

Tareas Pendientes

const taskItems = tasks.map((task) =>
  <li key={task.id}>
    {task.text}
  </li>
);

El Hook `useEffect`

Permite ejecutar "efectos secundarios" en componentes. Ideal para tareas como peticiones a APIs, suscripciones o manipulación manual del DOM después del renderizado.

Simulación de Petición a una API

Los datos del usuario aparecerán aquí...

useEffect(() => {
  // Este código se ejecuta CADA VEZ que
  // el estado 'shouldFetch' cambia.
  if (shouldFetch) {
    fetchUserData();
  }
}, [shouldFetch]); // Array de dependencias
useEffect(() => {
  // Este código se ejecuta UNA SOLA VEZ,
  // después del primer renderizado.
  console.log('Componente montado');
}, []); // Array de dependencias vacío