Componentes de orden superior en React

 

 

 

  • Accesibilidad para diseñadores, con Stéphanie Walter
  • Implemente rápidamente. Implementar inteligentemente

  • Índice
    1. Funciones de orden superior en JavaScript
      1. Un ejemplo de función personalizada de orden superior
    2. ¿Qué es un componente de orden superior?
      1. Datos sobre los HOC
    3. Estructura de un componente de orden superior
    4. Casos de uso
      1. Componentes de renderizado condicional
      2. Proporcionar componentes con un estilo específico
      3. Proporcione un componente con cualquier accesorio que desee
    5. Construyamos un componente de orden superior
    6. Conclusión
      1. Recursos y referencias

    En este tutorial, aprenderemos sobre los componentes de orden superior, la sintaxis de los componentes de orden superior y los casos de uso para ellos. En el proceso, construiremos un componente de orden superior a partir de un componente de React existente. Al final de este tutorial, comprenderá los conceptos básicos de los componentes de orden superior y cómo construirlos.

     

    Los componentes de orden superior (HOC) en React se inspiraron en funciones de orden superior en JavaScript. Un HOC es una técnica avanzada para reutilizar la lógica en componentes de React. Es un patrón creado a partir de la naturaleza compositiva de React.

    Los HOC básicamente incorporan el principio de programación de no repetirse (DRY), que probablemente haya encontrado en algún momento de su carrera como desarrollador de software. Es uno de los principios más conocidos del desarrollo de software y observarlo es muy importante al crear una aplicación o escribir código en general.

     

    En este tutorial aprenderemos qué es un HOC, su estructura básica, algunos casos de uso y, finalmente, un ejemplo.

    Nota: El conocimiento básico de React y JavaScript le resultará útil a medida que avance en este tutorial.

    Mejores prácticas de reacción

    React es una fantástica biblioteca de JavaScript para crear interfaces de usuario ricas. Proporciona una excelente abstracción de componentes para organizar sus interfaces en un código que funcione bien, y hay prácticamente cualquier cosa para la que pueda usarlo.Lea un artículo relacionado sobre React →

    Funciones de orden superior en JavaScript

    Antes de pasar a los HOC en React, analicemos brevemente las funciones de orden superior en JavaScript. Comprenderlos es fundamental para comprender nuestro tema de enfoque.

    Las funciones de orden superior en JavaScript toman algunas funciones como argumentos y devuelven otra función. Nos permiten abstraer acciones , no solo valores. Vienen en varias formas y nos ayudan a escribir menos código cuando operamos con funciones e incluso matrices.

    La parte más interesante del uso de funciones de orden superior es la composición. Podemos escribir pequeñas funciones que manejen una parte de la lógica. Luego, podemos componer funciones complejas utilizando las diferentes funciones pequeñas que hemos creado. Esto reduce los errores en nuestra base de código y hace que nuestro código sea mucho más fácil de leer y comprender.

    JavaScript tiene algunas de estas funciones ya integradas. Algunos ejemplos de funciones de orden superior son los siguientes:

    • .forEach()
      Esto itera sobre cada elemento de una matriz con el mismo código, pero no cambia ni muta la matriz, y devuelve indefinido.
    • .map()
      Este método transforma una matriz aplicando una función a todos sus elementos y luego construyendo una nueva matriz a partir de los valores devueltos.
    • .reduce()
      Este método ejecuta una función proporcionada para cada valor de la matriz (de izquierda a derecha).
    • .filter()
      Esto verifica cada elemento de una matriz para ver si cumple con ciertos criterios especificados en el filtermétodo y luego devuelve una nueva matriz con los elementos que coinciden con los criterios.

    Muchas funciones de orden superior están integradas en JavaScript y usted puede crear las suyas propias.

    Un ejemplo de función personalizada de orden superior

    Supongamos que se nos pide que escribamos una función que formatee números enteros como monedas, incluida alguna personalización para especificar el símbolo de la moneda y agregar un separador decimal para el monto de la moneda. Podemos escribir una función superior que tome el símbolo de moneda y también el separador decimal. Esta misma función luego formatearía el valor que se le pasara con el símbolo de moneda y operadores decimales. Llamaríamos a nuestra función de orden superior formatCurrency.

     

    const formatCurrency = function( currencySymbol, decimalSeparator ) { return function( value ) { const wholePart = Math.trunc( value / 100 ); let fractionalPart = value % 100; if ( fractionalPart 10 ) { fractionalPart = '0' + fractionalPart; } return `${currencySymbol}${wholePart}${decimalSeparator}${fractionalPart}`; }}

    formatCurrencyDevuelve una función con un símbolo de moneda fijo y un separador decimal.

    Luego le pasamos un valor al formateador y formateamos este valor con la función extrayendo su parte entera y la parte fraccionaria. El valor devuelto de esta función se construye mediante un literal de plantilla, que concatena el símbolo de moneda, la parte completa, el separador decimal y la parte fraccionaria.

    Usemos esta función de orden superior asignándole un valor y viendo el resultado.

     getLabel = formatCurrency( '$', '.' ); getLabel( 1999 )"$19.99" //formatted value getLabel( 2499 )"$24.99" //formatted value

    Es posible que hayas notado que creamos una variable llamada getLabel, luego asignamos nuestra formatCurrencyfunción de orden superior y luego pasamos los formateadores de moneda a la función, que es el símbolo de moneda y un separador decimal. Para hacer uso de la función, llamamos a getLabel, que ahora es una función, y le pasamos el valor que necesita ser formateado. ¡Eso es todo! Hemos creado un orden superior personalizado de nuestra elección.

    ¿Qué es un componente de orden superior?

    Un componente de orden superior (HOC) es un elemento avanzado para reutilizar la lógica en los componentes de React. Los componentes toman uno o más componentes como argumentos y devuelven un nuevo componente actualizado. Suena familiar, ¿verdad? Son similares a las funciones de orden superior, que toman algunas funciones como argumento y producen una nueva función.

    Los HOC se usan comúnmente para diseñar componentes con cierto comportamiento compartido de una manera que los conecte de manera diferente al patrón normal de estado a accesorios.

    Datos sobre los HOC

    1. No modificamos ni mutamos componentes. Creamos otros nuevos.
    2. Un HOC se utiliza para componer componentes para la reutilización de código.
    3. Un HOC es una función pura. No tiene efectos secundarios, devolviendo sólo un componente nuevo.

    A continuación se muestran algunos ejemplos de HOC del mundo real con los que quizás se haya encontrado:

    reaccionar-redux connect(mapStateToProps, mapDispatchToProps)(UserPage)
    enrutador de reacción withRouter(UserPage)
    material-ui withStyles(styles)(UserPage)

    Estructura de un componente de orden superior

    Un HOC está estructurado como una función de orden superior:

    • Es un componente.
    • Toma otro componente como argumento.
    • Luego, devuelve un nuevo componente.
    • El componente que devuelve puede representar el componente original que se le pasó.

    El siguiente fragmento muestra cómo se estructura un HOC en React:

     

    import React from 'react';// Take in a component as argument WrappedComponentconst higherOrderComponent = (WrappedComponent) = {// And return another component class HOC extends React.Component { render() { return WrappedComponent /; } } return HOC;};

    Podemos ver que higherOrderComponenttoma un componente ( WrappedComponent) y devuelve otro componente dentro de él. Con esta técnica, siempre que necesitemos reutilizar la lógica de un componente en particular para algo, podemos crear un HOC a partir de ese componente y usarlo donde queramos.

    Casos de uso

    En mi experiencia como ingeniero de front-end que ha estado escribiendo React por un tiempo, aquí hay algunos casos de uso para HOC.

    Mostrar un cargador mientras un componente espera datos

    La mayoría de las veces, al crear una aplicación web, necesitaríamos usar un cargador de algún tipo que se muestre mientras un componente espera que se pasen datos a sus accesorios. Podríamos usar fácilmente una solución en componentes para renderizar el cargador, lo cual funcionaría, pero no sería la solución más elegante. Mejor sería escribir un HOC común que pueda rastrear esos accesorios; y aunque esos accesorios no se han inyectado o están en un estado vacío, puede mostrar un estado de carga.

    Para explicar esto correctamente, creemos una lista de categorías de API públicas, utilizando su API abierta. Tendemos a manejar la carga de listas, para que nuestros clientes no entren en pánico cuando la API de la que obtenemos datos tarda tanto en responder.

    Generemos una aplicación React:

    npx create-react-app repos-list

    Un componente de lista básico se puede escribir de la siguiente manera:

    //List.jsimport React from 'react';const List = (props) = { const { repos } = props; if (!repos) return null; if (!repos.length) return pNo repos, sorry/p; return ( ul {repos.map((repo) = { return li key={repo.id}{repo.full_name}/li; })} /ul );};export default List;

    El código anterior es un componente de la lista. Dividamos el código en pequeños fragmentos para que podamos entender lo que está sucediendo.

    const List = (props) = {};

    Arriba, inicializamos nuestro componente funcional, llamado Listy le pasamos accesorios.

    const { repos } = props;

    Luego, creamos una constante, llamada repos, y la pasamos a los accesorios de nuestro componente, para que pueda usarse para modificar nuestro componente.

    if (!repos) return null;if (!repos.length) return pNo repos, sorry/p;

    Arriba, básicamente decimos que, si después de que se completó la búsqueda y el reposaccesorio aún está vacío, entonces debería regresar null. También estamos llevando a cabo una representación condicional aquí: si la longitud del reposaccesorio aún está vacía, entonces debería mostrar "Sin repositorios, lo siento" en nuestro navegador.

    return ( ul {repos.map((repo) = { return li key={repo.id}{repo.full_name}/li; })} /ul );

    Aquí, básicamente estamos mapeando la reposmatriz y devolviendo una lista de repositorios según sus nombres completos, con una clave única para cada entrada.

     

    Ahora, escribamos un HOC que maneje la carga, para hacer felices a nuestros usuarios.

    //withdLoading.jsimport React from 'react';function WithLoading(Component) { return function WihLoadingComponent({ isLoading, ...props }) { if (!isLoading) return Component {...props} /; return pHold on, fetching data might take some time./p; };}export default WithLoading;

    Esto mostraría el texto "Espera, la obtención de datos puede tardar algún tiempo" cuando la aplicación todavía está obteniendo datos y los accesorios se están inyectando en el estado. Usamos isLoadingpara determinar si el componente debe renderizarse. Vinos de Granada

    Ahora, en tu App.jsarchivo, puedes pasar la loadinglógica a WithLoading, sin preocuparte por ello en tu List.

    import React from 'react';import List from './components/List.js';import WithLoading from './components/withLoading.js';const ListWithLoading = WithLoading(List);class App extends React.Component { state = {{ }; componentDidMount() { this.setState({ loading: true }); fetch(`https://api.github.com/users/hacktivist123/repos`) .then((json) = json.json()) .then((repos) = { this.setState({ loading: false, repos: repos }); }); } render() { return ( ListWithLoading isLoading={this.state.loading} repos={this.state.repos} / ); }}export default App;

    El código anterior es nuestra aplicación completa. Analicémoslo para ver qué está pasando.

    class App extends React.Component { state = { loading: false, repos: null, }; componentDidMount() { this.setState({ loading: true }); fetch(`https://api.github.com/users/hacktivist123/repos`) .then((json) = json.json()) .then((repos) = { this.setState({ loading: false, repos: repos }); }); }

    Todo lo que estamos haciendo aquí es crear un componente de clase llamado App(), luego inicializar el estado con dos propiedades loading: false,y repos: null,. El estado inicial de loadinges false, mientras que el estado inicial de los repositorios también es null.

    Luego, cuando nuestro componente se está montando, configuramos el estado de la loadingpropiedad en truee inmediatamente realizamos una solicitud de recuperación a la URL de API que contiene los datos que necesitamos para completar nuestro Listcomponente. Una vez que se completa la solicitud, configuramos el loadingestado falsey lo completamos reposcon los datos que extrajimos de la solicitud de API.

    const ListWithLoading = WithLoading(List);

    Aquí, creamos un nuevo componente llamado ListWithLoadingy pasamos el WithLoadingHOC que creamos y también el Listcomponente que contiene.

    render() { return ( ListWithLoading isLoading={this.state.loading} repos={this.state.repos} / ); }

    Arriba, renderizamos el ListWithLoadingcomponente, que ha sido sobrecargado por el WithLoadingHOC que creamos y también el Listcomponente que contiene. Además, pasamos el loadingvalor del estado y el reposvalor del estado como accesorios al componente.

     

    Debido a que la página todavía está intentando extraer datos de la API, nuestro HOC mostrará el siguiente texto en el navegador.

    Estado de carga de la aplicación ( vista previa grande )

    Cuando finaliza la carga y los accesorios ya no están vacíos, los repositorios se mostrarán en la pantalla.

    Estado finalizado de la carga de la aplicación ( vista previa grande )

    Componentes de renderizado condicional

    Supongamos que tenemos un componente que debe representarse solo cuando un usuario está autenticado: es un componente protegido. Podemos crear un HOC llamado WithAuth()para envolver ese componente protegido y luego hacer una verificación en el HOC que representará solo ese componente en particular si el usuario ha sido autenticado.

    Un withAuth()HOC básico, según el ejemplo anterior, se puede escribir de la siguiente manera:

    // withAuth.jsimport React from "react";export function withAuth(Component) { return class AuthenticatedComponent extends React.Component { isAuthenticated() { return this.props.isAuthenticated; } /** * Render */ render() { const loginErrorMessage = ( div Please a href="/login"login/a in order to view this part of the application. /div ); return ( div { this.isAuthenticated === true ? Component {...this.props} / : loginErrorMessage } /div ); } };}export default withAuth;

    El código anterior es un HOC llamado withAuth. Básicamente, toma un componente y devuelve un nuevo componente, llamado AuthenticatedComponent, que verifica si el usuario está autenticado. Si el usuario no está autenticado, devuelve el loginErrorMessagecomponente; si el usuario está autenticado, devuelve el componente empaquetado.

    Nota: this.props.isAuthenticated debe configurarse desde la lógica de su aplicación. (O bien, utilice reaccionar-redux para recuperarlo del estado global).

    Para utilizar nuestro HOC en un componente protegido, lo usaríamos así:

    // MyProtectedComponent.jsimport React from "react";import {withAuth} from "./withAuth.js";export class MyProectedComponent extends React.Component { /** * Render */ render() { return ( div This is only viewable by authenticated users. /div ); }}// Now wrap MyPrivateComponent with the requireAuthentication function export default withAuth(MyPrivateComponent);

    Aquí, creamos un componente que solo pueden ver los usuarios autenticados. Incluimos ese componente en nuestro withAuthHOC para protegerlo de usuarios que no están autenticados.

    Proporcionar componentes con un estilo específico

    Continuando con el caso de uso anterior, según el estado de la interfaz de usuario que obtenga del HOC, puede representar estilos específicos para estados de la interfaz de usuario específicos. Por ejemplo, si surge la necesidad en varios lugares de estilos como backgroundColor, fontSizeetc., se pueden proporcionar a través de un HOC envolviendo el componente con uno que simplemente inyecte accesorios con el className.

     

    Tomemos como ejemplo un componente muy simple que representa "hola" y el nombre de una persona. Se necesita un nameaccesorio y algún otro accesorio que pueda afectar el XML de JavaScript (JSX) renderizado.

    // A simple component const HelloComponent = ({ name, ...otherProps }) = ( div {...otherProps}Hello {name}!/div);

    Creemos un HOC llamado withStylingque agregue algo de estilo al texto "hola".

    const withStyling = (BaseComponent) = (props) = ( BaseComponent {...props} style={{ fontWeight: 700, color: 'green' }} /);

    Para hacer uso del HOC en nuestro HelloComponent, envolvemos el HOC alrededor del componente. Creamos un componente puro, llamado EnhancedHelloy asignamos el HOC y nuestro HelloComponent, así:

    const EnhancedHello = withStyling(HelloComponent);

    Para realizar un cambio en nuestro HelloComponent, renderizamos el EnhancedHellocomponente:

    EnhancedHello name='World' /

    Ahora, el texto en nuestro HelloComponentse convierte en este:

    div style={{fontWeight: 700, color: 'green' }}Hello World/div

    Proporcione un componente con cualquier accesorio que desee

    Este es un caso de uso popular para los HOC. Podemos estudiar nuestra base de código y observar qué accesorios reutilizables se necesitan en todos los componentes. Luego, podemos tener un HOC contenedor para proporcionar a esos componentes el accesorio reutilizable.

    Usemos el ejemplo anterior:

    // A simple component const HelloComponent = ({ name, ...otherProps }) = ( div {...otherProps}Hello {name}!/div);

    Creemos un HOC llamado withNameChangeque establezca un nameaccesorio en un componente base en "Nuevo nombre".

    const withNameChange = (BaseComponent) = (props) = ( BaseComponent {...props} name='New Name' /);

    Para usar el HOC en nuestro HelloComponent, envolvemos el HOC alrededor del componente, creamos un componente puro llamado EnhancedHello2y asignamos el HOC y HelloComponentsimilares de esta manera:

    const EnhancedHello2 = withNameChange(HelloComponent);

    Para realizar un cambio en nuestro HelloComponent, podemos representar el EnhancedHellocomponente así:

    EnhancedHello /

    Ahora, el texto en nuestro HelloComponentse convierte en este:

    divHello New World/div

    Para cambiar el nameprop, todo lo que tenemos que hacer es esto:

    EnhancedHello name='Shedrack' /

    El texto en nuestro HelloComponentse convierte en este:

    divHello Shedrack/div

    Construyamos un componente de orden superior

    En esta sección, construiremos un HOC que toma un componente que tiene un nameaccesorio y luego usaremos el nameaccesorio en nuestro HOC.

     

    Entonces, genera una nueva aplicación React con create-react-app, así:

    npx create-react-app my-app

    Una vez generado, reemplace el código en su index.jsarchivo con el siguiente fragmento.

    import React from 'react';import { render } from 'react-dom';const Hello = ({ name }) = h1 Hello {name}! /h1;function withName(WrappedComponent) { return class extends React.Component { render() { return WrappedComponent name="Smashing Magazine" {...this.props} /; } };}const NewComponent = withName(Hello);const App = () = div NewComponent / /div;render(App /, document.getElementById('root'));

    Una vez que haya reemplazado el código en su index.jsarchivo, debería ver lo siguiente en su pantalla:

    Nuestra aplicación React ( vista previa grande )

    Repasemos el fragmento poco a poco.

    const Hello = ({ name }) = h1 Hello {name}! /h1;

    Aquí, creamos un componente funcional que tiene un accesorio llamado name. En este componente funcional, representamos "Hola" y el valor del nameaccesorio en una h1etiqueta.

    function withName(WrappedComponent) { return class extends React.Component { render() { return WrappedComponent name="Smashing Magazine" {...this.props} /; } };}

    Arriba, creamos un componente funcional de orden superior llamado withName(). Luego, devolvemos un componente de clase anónimo dentro que representa el componente envuelto en el HOC. Y asignamos un valor al accesorio del componente envuelto.

    const NewComponent = withName(Hello);

    Aquí, creamos un nuevo componente llamado NewComponent. Usamos el HOC que creamos y le asignamos el componente funcional que creamos al comienzo del código base, llamado hello.

    const App = () = div NewComponent / /div;render(App /, document.getElementById('root'));

    Todo lo que estamos haciendo arriba es crear otro componente funcional, llamado App. Representa el archivo NewComponentque actualizamos con nuestro HOC en un formato div. Luego, usamos la función reaccionar-dom renderpara mostrar el componente en el navegador.

    ¡Eso es todo lo que tenemos que hacer! Nuestra withNamefunción toma un componente como argumento y devuelve un HOC. Dentro de unos meses, si decidimos cambiar las cosas, solo tendremos que editar nuestro HOC.

    Conclusión

    Espero que hayas disfrutado trabajando en este tutorial. Puede leer más sobre componentes de orden superior en las referencias que se enumeran a continuación. Si tiene alguna pregunta, déjela en la sección de comentarios a continuación. Estaré feliz de responder a todos.

    Recursos y referencias

    • “ Funciones de orden superior ”, JavaScript elocuente, Marijn Haverbeke
    • “ Introducción a los componentes de orden superior (HOC) en React ”, Johnson Ogwuru
    • " Reaccionar componentes de orden superior ", Tyler McGinnis
    • “ Explicación sencilla de los componentes de orden superior (HOC) ”, Jakob Lind
    • “ Una introducción rápida a los componentes de orden superior de React ”, Patrick Moriarty, Alligator.io
    • “ Funciones de orden superior en JavaScript ”, Zslot Nagy

    (ks, ra, il, al)Explora más en

    • Reaccionar
    • redux
    • Herramientas
    • javascript





    Tal vez te puede interesar:

    1. ¿Deberían abrirse los enlaces en ventanas nuevas?
    2. 24 excelentes tutoriales de AJAX
    3. 70 técnicas nuevas y útiles de AJAX y JavaScript
    4. Más de 45 excelentes recursos y repositorios de fragmentos de código

    Componentes de orden superior en React

    Componentes de orden superior en React

    Accesibilidad para diseñadores, con Stéphanie Walter Implemente rápidamente. Implementar inteligentemente Índice

    programar

    es

    https://pseint.es/static/images/programar-componentes-de-orden-superior-en-react-1035-0.jpg

    2024-04-04

     

    Componentes de orden superior en React
    Componentes de orden superior en React

    Si crees que alguno de los contenidos (texto, imagenes o multimedia) en esta página infringe tus derechos relativos a propiedad intelectual, marcas registradas o cualquier otro de tus derechos, por favor ponte en contacto con nosotros en el mail [email protected] y retiraremos este contenido inmediatamente

     

     

    Top 20