React Fundamentals
React Fundamentals Texto Leccion

Patrones comunes de useEffect

Patrones practicos Fetch con async/await function Users() { const [users, setUsers] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { // No puedes hacer useEffect async directamente // Crea una funcion async dentro const fetchUsers = async () => { try { setLoading(true); const res = await fetch('/api/users'); if (!res.ok) throw new Error('Error al cargar'); const data = await res.json(); setUsers(data); } catch (err) { setEr
Tiempo de estudio
15 Min

Patrones practicos



Fetch con async/await



function Users() {
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);

useEffect(() => {
// No puedes hacer useEffect async directamente
// Crea una funcion async dentro
const fetchUsers = async () => {
try {
setLoading(true);
const res = await fetch('/api/users');

if (!res.ok) throw new Error('Error al cargar');

const data = await res.json();
setUsers(data);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};

fetchUsers();
}, []);

if (loading) return <p>Cargando...</p>;
if (error) return <p>Error: {error}</p>;

return (
<ul>
{users.map(u => <li key={u.id}>{u.name}</li>)}
</ul>
);
}


Debounce de busqueda



function Search() {
const [query, setQuery] = useState('');
const [results, setResults] = useState([]);

useEffect(() => {
if (!query) {
setResults([]);
return;
}

// Espera 300ms antes de buscar
const timer = setTimeout(() => {
fetch(`/api/search?q=${query}`)
.then(res => res.json())
.then(setResults);
}, 300);

return () => clearTimeout(timer);
}, [query]);

return (
<div>
<input
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Buscar..."
/>
<ul>
{results.map(r => <li key={r.id}>{r.title}</li>)}
</ul>
</div>
);
}


Local Storage



function useLocalStorage(key, initialValue) {
const [value, setValue] = useState(() => {
const saved = localStorage.getItem(key);
return saved ? JSON.parse(saved) : initialValue;
});

useEffect(() => {
localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);

return [value, setValue];
}

// Uso
function App() {
const [theme, setTheme] = useLocalStorage('theme', 'light');

return (
<button onClick={() => setTheme(t => t === 'light' ? 'dark' : 'light')}>
Tema: {theme}
</button>
);
}


Evitar efectos innecesarios



// MAL - efecto innecesario
function Form() {
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
const [fullName, setFullName] = useState('');

useEffect(() => {
setFullName(firstName + ' ' + lastName);
}, [firstName, lastName]);
}

// BIEN - calcula durante el render
function Form() {
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');

// Derivado, no necesita estado
const fullName = firstName + ' ' + lastName;
}



Practica de portfolio


Convierte esta leccion en evidencia real: arma una entrega pequena que puedas mostrar en una entrevista, en LinkedIn o en tu portfolio. Trabaja con un caso propio o con una empresa ficticia, pero deja claro el problema, la decision y el resultado.



  • Entregable: una captura, documento, repositorio o tablero con el resultado final.

  • Checklist: objetivo, pasos seguidos, criterio de calidad y mejora pendiente.

  • Mini-rubrica: si otra persona lo revisa, debe entender que hiciste, por que y como repetirlo.

Texto Leccion 3/13
Estas viendo
Patrones comunes de useEffect
Hablar por WhatsAppContactar por WhatsApp