"Si un trabajador quiere hacer bien su trabajo, primero debe afilar sus herramientas." - Confucio, "Las Analectas de Confucio. Lu Linggong"
Página delantera > Programación > Patrones de diseño de ReactJS: escritura de componentes robustos y escalables

Patrones de diseño de ReactJS: escritura de componentes robustos y escalables

Publicado el 2024-11-07
Navegar:114

ReactJS Design Patterns: Writing Robust and Scalable Components

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.

1. Patrón de componentes de presentación y contenedor

El patrón Contenedor y Presentación separa los componentes en dos categorías:

  • Componentes presentacionales: céntrese en cómo se ven las cosas (UI).
  • Componentes del contenedor: céntrese en cómo funcionan las cosas (lógica y gestión de estado).

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 }) => (
  
    {users.map((user) => (
  • {user.name}
  • ))}
); export default UserList;
// 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.

2. Patrón de componentes de orden superior (HOC)

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.

3. Patrón de accesorios de renderizado

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.

4. Patrón de ganchos personalizados

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) return 
Loading...
; return (
    {data.map((post) => (
  • {post.title}
  • ))}
); }; export default App;

El gancho personalizado useFetch encapsula la lógica de obtención de datos, que se puede reutilizar en diferentes componentes.

5. Patrón de componentes compuestos

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 = () => (
  
    Tab 1
    Tab 2
    Content for Tab 1
    Content for Tab 2
  
);

export default App;

El componente Tabs administra el estado, mientras que los componentes Tab y TabPanel trabajan juntos para mostrar el contenido con pestañas.

6. Patrón de componentes controlados y no controlados

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.

7. Patrón de fábrica de ganchos

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))} />

Name: {states.name}

Age: {states.age}

); }; export default App;

Esta fábrica de ganchos crea y administra dinámicamente múltiples estados, lo que brinda flexibilidad y un código más limpio.

Conclusión

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?

Declaración de liberación Este artículo se reproduce en: https://dev.to/abhishek_kumar_d9009a7ae6/reactjs-design-patterns-writing-robust-and-scalable-components-2a6h?1 Si hay alguna infracción, comuníquese con [email protected] para eliminar él
Último tutorial Más>

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