
Gabriel Jiménez | Hace 5 meses
Cuando aprendemos a programar en React, uno de los principales problemas al que nos enfrentamos es: compartir un mismo estado entre diferentes componentes. Para evitar este problema, encapsulamos toda nuestra lógica en un componente. Sin embargo, cuando las aplicaciones crecen esto no suele ser mantenible a largo plazo. Otra alternativa es utilizar la técnica Lifting State Up, pero no todos saben de qué trata.
Aprendamos qué es Lifting State Up, cómo y por qué utilizarlo y finalmente, veamos un ejemplo práctico.
En resumen, el componente Control central de datos trabaja como: fuente única de verdad del estado nombre.
Lifting State Up es importante porque, nos obliga a mantener una mentalidad de separación de responsabilidades. Al hacerlo, estamos haciendo que nuestros componentes sean escalables y fáciles de mantener.
En nuestro ejemplo de la Figura 1, la responsabilidad es: mantener el estado nombre como única fuente de verdad y sincronizarlo con sus dependientes. Ya que se el por qué, ahora como detecto que debo utilizarlo.
Algunas señales son:
Para ejemplificar el uso de Lifting State Up, supongamos que necesitamos una aplicación para listar y dar de alta películas.
Una solución sería crear un único componente donde se realicen ambas tareas, pero como ya vimos anteriormente, separa responsabilidades es útil y sano para nuestras aplicaciones.
Para nuestro caso, tenemos tres componentes con responsabilidades bien definidas:
Se encarga de crear y notificar a su componente padre sobre las películas creadas.
import { useState } from 'react'; function MovieForm({ onChange }) { const [name, setName] = useState(''); const [rating, setRating] = useState(''); const handleSubmit = (e) => { e.preventDefault(); if (!name || !rating) return; onChange({ name, rating: Number(rating) }); setName(''); setRating(''); }; return ( <form onSubmit={handleSubmit}> <input placeholder="Nombre de la película" value={name} onChange={(e) => setName(e.target.value)} /> <input placeholder="Puntuación" type="number" value={rating} onChange={(e) => setRating(e.target.value)} /> <button type="submit">Agregar</button> </form> ); } export default MovieForm;
Lista las películas almacenadas en el componte App.
function MovieList({ movies }) { return ( <ul> {movies.map((movie, index) => ( <li key={index}> {movie.name} - Puntuación: {movie.rating} </li> ))} </ul> ); } export default MovieList;
Trabaja como única fuente de verdad de las películas creadas. Además, permite sincronizarlas con el componente MovieList.
import { useState } from 'react'; import MovieForm from './MovieForm'; import MovieList from './MovieList'; function App() { const [movies, setMovies] = useState([]); const handleAddMovie = (movie) => { setMovies((prev) => [...prev, movie]); }; return ( <> <MovieForm onChange={handleAddMovie} /> <MovieList movies={movies} /> </> ); } export default App;
Nota: Saber que props debo de pasar a mis componentes es otra buena práctica en el desarrollo de software en React. Te recomiendo que leas mi artículo: React props: buenas prácticas para código más limpio y escalable
Conclusión
Lifting State Up nos hace tener una mentalidad de separación de responsabilidades al mantener nuestros componentes como fuente única de verdad. Sin embargo, es importante no abusar porque no es lo mismo sincronizar data entre uno o dos componentes que hacerlo con más de diez.
Si quieres aprender más sobre como mejorar la calidad de tu código en tus aplicaciones React, te recomiendo mi programa: Mentalidad de pruebas