11-funcion tipo flecha
Tutorial: Funciones Flecha en React
Introducción
Las funciones flecha (arrow functions) son una característica de ES6 que ofrece una sintaxis más concisa para escribir funciones en JavaScript. En React, son ampliamente utilizadas para definir componentes, manejar eventos y más.
Tabla de Contenidos
Sintaxis Básica
Ventajas en React
Uso en Componentes
Manejo de Eventos
Consideraciones
Ejemplo Práctico
1. Sintaxis Básica {#sintaxis-basica}
javascript
// Función tradicional
function suma(a, b) {
return a + b;
}
// Función flecha equivalente
const suma = (a, b) => {
return a + b;
};
// Si solo hay una expresión, se puede omitir {} y return
const suma = (a, b) => a + b;
// Un solo parámetro: los paréntesis son opcionales
const cuadrado = x => x * x;
// Sin parámetros: paréntesis obligatorios
const saludar = () => console.log("Hola");
2. Ventajas en React {#ventajas-en-react}
Sintaxis más concisa: Menos código boilerplate
No vinculan su propio this: El this se hereda del contexto circundante
Ideal para callbacks y handlers: Evitan problemas con this en eventos
3. Uso en Componentes {#uso-en-componentes}
Componente Funcional
// Función tradicional
function MiComponente(props) {
return <div>Hola, {props.nombre}</div>;
}
// Con función flecha
const MiComponente = (props) => {
return <div>Hola, {props.nombre}</div>;
};
// Versión más concisa (return implícito)
const MiComponente = (props) => <div>Hola, {props.nombre}</div>;
Componente con Estado (Hooks)
jsx
import React, { useState } from 'react';
// Con función flecha
const Contador = () => {
const [count, setCount] = useState(0);
return (
<div>
<p>Contador: {count}</p>
<button onClick={() => setCount(count + 1)}>
Incrementar
</button>
</div>
);
};
4. Manejo de Eventos {#manejo-de-eventos}
Métodos en Componentes de Clase
class MiComponente extends React.Component {
// Función flecha como método de instancia
handleClick = () => {
console.log('Clic', this.props);
// 'this' está correctamente vinculado
};
render() {
return <button onClick={this.handleClick}>Haz clic</button>;
}
}
En Componentes Funcionales
const MiComponente = () => {
// Handler como función flecha dentro del componente
const handleClick = () => {
console.log('Botón clickeado');
};
// Handler inline con función flecha
const handleInputChange = (event) => {
console.log('Valor:', event.target.value);
};
return (
<div>
<button onClick={handleClick}>Haz clic</button>
<input onChange={handleInputChange} />
{/* Handler inline directo */}
<button onClick={() => console.log('Click directo')}>
Botón directo
</button>
</div>
);};
5. Consideraciones {#consideraciones}
1. Return Implícito vs Explícito
// Return implícito (sin llaves)
const Lista = ({ items }) => (
<ul>
{items.map(item => <li key={item.id}>{item.name}</li>)}
</ul>
);
// Return explícito (con llaves)
const Lista = ({ items }) => {
const itemsFiltrados = items.filter(item => item.activo);
return (
<ul>
{itemsFiltrados.map(item => <li key={item.id}>{item.name}</li>)}
</ul>
);
};
2. Problemas Comunes con this
class ComponenteProblema extends React.Component {
state = { valor: 0 };
// ❌ PROBLEMA: 'this' será undefined
handleClick() {
console.log(this.state.valor); // Error: this es undefined
}
// ✅ SOLUCIÓN: Usar función flecha
handleClickOk = () => {
console.log(this.state.valor); // Funciona correctamente
};
render() {
return (
<button onClick={this.handleClickOk}>Haz clic</button>
);
}}
3. Rendimiento y Re-renderizados
jsx
const Componente = () => {
const [contador, setContador] = useState(0);
// ❌ Se crea una nueva función en cada render
const handleClick = () => setContador(contador + 1);
return <button onClick={handleClick}>Incrementar</button>;
};
jsx
import React, { useState, useCallback } from 'react';
const ComponenteOptimizado = () => {
const [contador, setContador] = useState(0);
// ✅ Se memoriza la función
const handleClick = useCallback(() => {
setContador(contador + 1);
}, [contador]);
return <button onClick={handleClick}>Incrementar</button>;
};
6. Ejemplo Práctico {#ejemplo-practico}
Aplicación de Tareas (Todo List)
import React, { useState } from 'react';
const TodoApp = () => {
const [tareas, setTareas] = useState([]);
const [nuevaTarea, setNuevaTarea] = useState('');
// Handler para agregar tarea
const agregarTarea = () => {
if (nuevaTarea.trim()) {
setTareas([...tareas, {
id: Date.now(),
texto: nuevaTarea,
completada: false
}]);
setNuevaTarea('');
}
};
// Handler para marcar como completada
const toggleCompletada = (id) => {
setTareas(tareas.map(tarea =>
tarea.id === id
? { ...tarea, completada: !tarea.completada }
: tarea
));
};
// Handler para eliminar tarea
const eliminarTarea = (id) => {
setTareas(tareas.filter(tarea => tarea.id !== id));
};
return (
<div style={styles.container}>
<h1>Lista de Tareas</h1>
<div style={styles.form}>
<input
type="text"
value={nuevaTarea}
onChange={(e) => setNuevaTarea(e.target.value)}
placeholder="Nueva tarea"
style={styles.input}
onKeyPress={(e) => e.key === 'Enter' && agregarTarea()}
/>
<button onClick={agregarTarea} style={styles.button}>
Agregar
</button>
</div>
<ul style={styles.lista}>
{tareas.map((tarea) => (
<li key={tarea.id} style={styles.item}>
<span
style={{
...styles.texto,
textDecoration: tarea.completada ? 'line-through' : 'none',
color: tarea.completada ? '#888' : '#000'
}}
onClick={() => toggleCompletada(tarea.id)}
>
{tarea.texto}
</span>
<button
onClick={() => eliminarTarea(tarea.id)}
style={styles.botonEliminar}
>
Eliminar
</button>
</li>
))}
</ul>
{tareas.length === 0 && (
<p style={styles.vacio}>No hay tareas pendientes</p>
)}
</div>
);
};
// Estilos para el ejemplo
const styles = {
container: {
maxWidth: '500px',
margin: '0 auto',
padding: '20px',
fontFamily: 'Arial, sans-serif'
},
form: {
display: 'flex',
marginBottom: '20px'
},
input: {
flex: 1,
padding: '10px',
fontSize: '16px',
border: '1px solid #ddd',
borderRadius: '4px 0 0 4px'
},
button: {
padding: '10px 20px',
fontSize: '16px',
backgroundColor: '#007bff',
color: 'white',
border: 'none',
borderRadius: '0 4px 4px 0',
cursor: 'pointer'
},
lista: {
listStyle: 'none',
padding: 0
},
item: {
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
padding: '10px',
borderBottom: '1px solid #eee'
},
texto: {
cursor: 'pointer',
flex: 1
},
botonEliminar: {
backgroundColor: '#dc3545',
color: 'white',
border: 'none',
padding: '5px 10px',
borderRadius: '3px',
cursor: 'pointer'
},
vacio: {
textAlign: 'center',
color: '#888',
fontStyle: 'italic'
}
};
export default TodoApp;
Resumen
Usa funciones flecha para componentes funcionales y handlers de eventos
Aprovecha el return implícito cuando sea apropiado
Considera el rendimiento con useCallback para funciones que se pasan a hijos
Evita problemas con this en componentes de clase usando funciones flecha como métodos
Comentarios
Publicar un comentario