Los patrones de diseño en ReactJS brindan soluciones estandarizadas y probadas a problemas comunes en el desarrollo de aplicaciones. El uso de estos patrones no solo hace que su código sea más legible y fácil de mantener, sino que también mejora su escalabilidad y solidez. Profundicemos en algunos de los patrones de diseño de ReactJS más populares, con ejemplos para ilustrar su uso.
El patrón Contenedor y Presentación separa los componentes en dos categorías:
Esta separación permite una mejor reutilización, pruebas más sencillas y un código más limpio.
Ejemplo: componentes de presentación y de contenedor
// Presentational Component: Displaying User List (UserList.js) import React from 'react'; const UserList = ({ users }) => (
// Container Component: Fetching User Data (UserContainer.js) import React, { useState, useEffect } from 'react'; import UserList from './UserList'; const UserContainer = () => { const [users, setUsers] = useState([]); useEffect(() => { const fetchUsers = async () => { const response = await fetch('https://jsonplaceholder.typicode.com/users'); const data = await response.json(); setUsers(data); }; fetchUsers(); }, []); return; }; export default UserContainer;
Aquí, UserList es un componente de presentación que recibe a los usuarios como accesorios, mientras que UserContainer maneja la obtención de datos y la administración del estado.
Un Componente de orden superior (HOC) es una función que toma un componente como argumento y devuelve un nuevo componente. Los HOC se utilizan habitualmente para cuestiones transversales como la autenticación, el registro o la mejora del comportamiento de los componentes.
Ejemplo: creación de un HOC para autorización
// withAuthorization.js (HOC for Authorization) import React from 'react'; const withAuthorization = (WrappedComponent) => { return class extends React.Component { componentDidMount() { if (!localStorage.getItem('authToken')) { // Redirect to login if not authenticated window.location.href = '/login'; } } render() { return; } }; }; export default withAuthorization;
// Dashboard.js (Component Wrapped with HOC) import React from 'react'; import withAuthorization from './withAuthorization'; const Dashboard = () =>Welcome to the Dashboard
; export default withAuthorization(Dashboard);
Al empaquetar el Panel con withAuthorization, te aseguras de que solo los usuarios autenticados puedan acceder a él.
El patrón Render Props implica compartir código entre componentes utilizando un accesorio cuyo valor es una función. Este patrón es útil para el renderizado dinámico basado en ciertas condiciones o estados.
Ejemplo: uso de accesorios de renderizado para el seguimiento del mouse
// MouseTracker.js (Component with Render Props) import React, { useState } from 'react'; const MouseTracker = ({ render }) => { const [position, setPosition] = useState({ x: 0, y: 0 }); const handleMouseMove = (event) => { setPosition({ x: event.clientX, y: event.clientY }); }; return{render(position)}; }; export default MouseTracker;
// App.js (Using Render Props) import React from 'react'; import MouseTracker from './MouseTracker'; const App = () => (( Mouse position: ({x}, {y})
)} /> ); export default App;
El componente MouseTracker utiliza un accesorio de renderizado para pasar datos de posición del mouse a cualquier componente, lo que lo hace altamente reutilizable.
Los ganchos personalizados le permiten encapsular y reutilizar la lógica con estado en múltiples componentes. Este patrón promueve la reutilización del código y una separación clara de preocupaciones.
Ejemplo: creación de un enlace personalizado para recuperar datos
// useFetch.js (Custom Hook) import { useState, useEffect } from 'react'; const useFetch = (url) => { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { const fetchData = async () => { const response = await fetch(url); const result = await response.json(); setData(result); setLoading(false); }; fetchData(); }, [url]); return { data, loading }; }; export default useFetch;
// App.js (Using the Custom Hook) import React from 'react'; import useFetch from './useFetch'; const App = () => { const { data, loading } = useFetch('https://jsonplaceholder.typicode.com/posts'); if (loading) returnLoading...; return (
El gancho personalizado useFetch encapsula la lógica de obtención de datos, que se puede reutilizar en diferentes componentes.
El patrón Componentes compuestos permite que los componentes trabajen juntos para gestionar el estado y el comportamiento. Este patrón es útil para crear componentes de interfaz de usuario complejos, como pestañas, acordeones o menús desplegables.
Ejemplo: creación de pestañas con componentes compuestos
// Tabs.js (Parent Component) import React, { useState } from 'react'; const Tabs = ({ children }) => { const [activeIndex, setActiveIndex] = useState(0); return React.Children.map(children, (child, index) => React.cloneElement(child, { isActive: index === activeIndex, setActiveIndex, index }) ); }; const Tab = ({ children, isActive, setActiveIndex, index }) => ( ); const TabPanel = ({ children, isActive }) => (isActive ?{children}: null); Tabs.Tab = Tab; Tabs.TabPanel = TabPanel; export default Tabs;
// App.js (Using Compound Components) import React from 'react'; import Tabs from './Tabs'; const App = () => (); export default App; Tab 1 Tab 2 Content for Tab 1 Content for Tab 2
El componente Tabs administra el estado, mientras que los componentes Tab y TabPanel trabajan juntos para mostrar el contenido con pestañas.
Los componentes controlados son completamente administrados por el estado de React, mientras que los componentes no controlados dependen del DOM para su estado. Ambos tienen sus usos, pero generalmente se prefieren los componentes controlados por su coherencia y facilidad de mantenimiento.
Ejemplo: componentes controlados versus no controlados
// Controlled Component (TextInputControlled.js) import React, { useState } from 'react'; const TextInputControlled = () => { const [value, setValue] = useState(''); return ( setValue(e.target.value)} /> ); }; export default TextInputControlled;
// Uncontrolled Component (TextInputUncontrolled.js) import React, { useRef } from 'react'; const TextInputUncontrolled = () => { const inputRef = useRef(); const handleClick = () => { console.log(inputRef.current.value); }; return ( > ); }; export default TextInputUncontrolled;
En componentes controlados, React controla completamente el estado del formulario, mientras que en componentes no controlados, el estado es administrado por el propio DOM.
El patrón Hooks Factory implica la creación de ganchos que generan y administran dinámicamente múltiples estados o comportamientos, proporcionando una forma flexible de administrar lógica compleja.
Ejemplo: Gestión dinámica de estados con Hooks Factory
// useDynamicState.js (Hook Factory) import { useState } from 'react'; const useDynamicState = (initialStates) => { const states = {}; const setters = {}; initialStates.forEach(([key, initialValue]) => { const [state, setState] = useState(initialValue); states[key] = state; setters[key] = setState; }); return [states, setters]; }; export default useDynamicState;
// App.js (Using the Hooks Factory) import React from 'react'; import useDynamicState from './useDynamicState'; const App = () => { const [states, setters] = useDynamicState([ ['name', ''], ['age', 0], ]); return (setters .name(e.target.value)} /> setters.age(parseInt(e.target.value))} />); }; export default App;Name: {states.name}
Age: {states.age}
Esta fábrica de ganchos crea y administra dinámicamente múltiples estados, lo que brinda flexibilidad y un código más limpio.
Al aprovechar estos patrones de diseño, puede crear aplicaciones React que sean más sólidas, escalables y fáciles de mantener. Estos patrones lo ayudan a escribir código limpio y reutilizable que cumple con las mejores prácticas, lo que garantiza que su aplicación sea más fácil de desarrollar y administrar con el tiempo.
¿Te gustaría profundizar en alguno de estos patrones o explorar otros temas?
Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.
Copyright© 2022 湘ICP备2022001581号-3