Cómo encapsular un paquete de JavaScript para usarlo en React

Introducción

Índice
  1. Introducción
  • Prerrequisitos
  • Paso 1: Comprender el widget de JavaScript
  • Paso 2: determinar qué debe hacer un componente contenedor
  • Paso 3: Implementación de un contenedor de React
  • Paso 4: Sincronización de las actualizaciones de las propiedades de la cuadrícula
  • Paso 5: Exponer la API
  • Conclusión
  • Los proyectos web complejos suelen requerir el uso de widgets de terceros. Pero ¿qué sucede si estás usando un framework y el widget solo está disponible en JavaScript puro?

    Para utilizar un widget de JavaScript en su proyecto, el mejor enfoque sería crear un contenedor específico del marco.

    ag-Grides un widget de JavaScript para mostrar información en una cuadrícula de datos. Le permite ordenar, filtrar y seleccionar información de forma dinámica. ag-GridTambién proporciona un contenedor de React, ag-grid-react.

    En este artículo, utilizarás ag-grid-communityy ag-grid-reactcomo base para aprender a encapsular un widget de terceros en un componente de React. Configurarás la asignación entre React Props y las opciones de configuración del widget. Además, expondrás la API de un widget a través de un componente de React.

    Prerrequisitos

    Para seguir este artículo necesitarás:

    • Si tienes alguna familiaridad con React, puedes echar un vistazo a nuestra serie Cómo programar en React.js .

    Paso 1: Comprender el widget de JavaScript

    En general, la mayoría de los widgets de JavaScript tienen:

    • Opciones de configuración
    • Una API pública
    • Eventos retransmitidos

    Así es exactamente como interactúas con ag-Grid. Puedes encontrar una buena descripción de las propiedades, eventos, devoluciones de llamadas y API de la cuadrícula en la documentación oficial .

    En resumen, la cuadrícula de datos define:

    • Propiedades de cuadrícula que habilitan funciones de la cuadrícula, como la animación de filas.
    • API de cuadrícula para interactuar con la cuadrícula en tiempo de ejecución (por ejemplo, para obtener todas las filas seleccionadas)
    • Eventos de cuadrícula emitidos por la cuadrícula cuando ocurren ciertos eventos en la cuadrícula, como la clasificación de filas o la selección de filas
    • Las devoluciones de llamada de la cuadrícula se utilizan para proporcionar información desde su aplicación a la cuadrícula cuando la necesita (por ejemplo, se llama a una devolución de llamada cada vez que se muestra un menú que permite que su aplicación personalice el menú)

    A continuación se muestra una configuración básica de JavaScript puro que demuestra el uso de las opciones de cuadrícula:

    let gridOptions = {    // PROPERTIES - object properties, myRowData and myColDefs are created somewhere in your application    rowData: myRowData,    columnDefs: myColDefs,    // PROPERTIES - simple boolean / string / number properties    pagination: true,    rowSelection: 'single',    // EVENTS - add event callback handlers    onRowClicked: function(event) { console.log('a row was clicked'); },    onColumnResized: function(event) { console.log('a column was resized'); },    onGridReady: function(event) { console.log('the grid is now ready'); },    // CALLBACKS    isScrollLag: function() { return false; }}

    Primero, la cuadrícula de datos de JavaScript se inicializa de la siguiente manera:

    new Grid(this._nativeElement, this.gridOptions, ...);

    Luego, ag-Gridadjunta el objeto con métodos API que gridOptionsse pueden usar para controlar la cuadrícula de datos de JavaScript:

    // get the grid to refreshgridOptions.api.refreshView();

    Sin embargo, cuando ag-Gridse utiliza como un componente de React, no creamos una instancia de la cuadrícula de datos directamente. Esa es la tarea del componente contenedor. Todas las interacciones con la instancia de ag-Gridocurren a través de la instancia del componente.

    Por ejemplo, no tenemos acceso directo al objeto API asociado a la cuadrícula. Accederemos a él a través de la instancia del componente.

    Paso 2: determinar qué debe hacer un componente contenedor

    Nunca pasamos opciones de configuración ni devoluciones de llamadas directamente a la red. Un componente contenedor de React toma las opciones y las devoluciones de llamadas a través de React Props.

    Todas las opciones de cuadrícula que están disponibles para la cuadrícula de JavaScript estándar también deberían estar disponibles en la cuadrícula de datos de Reactag-Grid . Tampoco escuchamos directamente los eventos en la instancia de . Si lo usamos ag-Gridcomo un componente de React, todos los eventos emitidos por ag-Griddeberían estar disponibles a través de las propiedades de los componentes de React.

    Todo esto significa que un contenedor de cuadrícula de datos específico de React ag-Griddebería:

    • Implementar un mapeo entre enlaces de entrada (como rowData) y ag-Gridlas opciones de configuración de
    • Debe escuchar los eventos emitidos por ag-Gridy definirlos como salidas de componentes.
    • escuchar los cambios en los enlaces de entrada del componente y actualizar las opciones de configuración en la cuadrícula
    • Exponer API adjunta a ag-Gridtravés gridOptionsde sus propiedades

    El siguiente ejemplo demuestra cómo se configura la cuadrícula de datos de React en una plantilla utilizando React Props:

    AgGridReact    // useful for accessing the component directly via ref - optional    ref="agGrid"    // simple attributes, not bound to any state or prop    rowSelection="multiple"    // these are bound props, so can use anything in React state or props    columnDefs={this.props.columnDefs}    showToolPanel={this.state.showToolPanel}    // this is a callback    isScrollLag={this.myIsScrollLagFunction}    // these are registering event callbacks    onCellClicked={this.onCellClicked}    onColumnResized={this.onColumnEvent}    // inside onGridReady, you receive the grid APIs if you want them    onGridReady={this.onGridReady}/

    Ahora que entendemos el requisito, veamos cómo lo implementamos en ag-Grid.

    Paso 3: Implementación de un contenedor de React

    Primero, necesitamos definir un componente React AgGridReactque represente nuestra cuadrícula de datos React en plantillas. Este componente renderizará un DIVelemento que servirá como contenedor para la cuadrícula de datos. Para obtener el DIVelemento nativo, usamos la funcionalidad Refs :

    export class AgGridReact extends React.Component {    protected eGridDiv: HTMLElement;    render() {        return React.createElement("div", {            style: ...,            ref: e = {                this.eGridDiv = e;            }        }, ...);    }}

    Antes de poder crear una instancia ag-Grid, también debemos recopilar todas las opciones. Todas ag-Gridlas propiedades y eventos vienen como React Props en el AgGridReactcomponente. La gridOptionspropiedad se usa para almacenar todas las opciones de la cuadrícula de datos. Necesitamos copiar todas las opciones de configuración de React Props tan pronto como estén disponibles.

    Para ello, hemos implementado la copyAttributesToGridOptionsfunción. Se trata de una función de utilidad que copia propiedades de un objeto a otro:

    export class ComponentUtil {    ...    public static copyAttributesToGridOptions(gridOptions, component, ...) {        ...        // copy all grid properties to gridOptions object        ComponentUtil.ARRAY_PROPERTIES            .concat(ComponentUtil.STRING_PROPERTIES)            .concat(ComponentUtil.OBJECT_PROPERTIES)            .concat(ComponentUtil.FUNCTION_PROPERTIES)            .forEach(key = {                if (typeof component[key] !== 'undefined') {                    gridOptions[key] = component[key];                }            });         ...         return gridOptions;    }}

    Las opciones se copian en el componentDidMountmétodo de ciclo de vida después de que se hayan actualizado todas las propiedades. Este es también el gancho donde instanciamos la cuadrícula. Necesitamos pasar un elemento DOM nativo a la cuadrícula de datos cuando se instancia, por lo que usaremos el DIVelemento capturado mediante la funcionalidad de referencias:

    export class AgGridReact extends React.Component {    gridOptions: AgGrid.GridOptions;    componentDidMount() {        ...        let gridOptions = this.props.gridOptions || {};        if (AgGridColumn.hasChildColumns(this.props)) {            gridOptions.columnDefs = AgGridColumn.mapChildColumnDefs(this.props);        }        this.gridOptions = AgGrid.ComponentUtil.copyAttributesToGridOptions(gridOptions, this.props);        new AgGrid.Grid(this.eGridDiv, this.gridOptions, gridParams);        this.api = this.gridOptions.api;        this.columnApi = this.gridOptions.columnApi;    }}

    Arriba puedes ver que también verificamos si hay elementos secundarios que se pasan como columnas y los agregamos a las opciones de configuración como definiciones de columnas:

    if (AgGridColumn.hasChildColumns(this.props)) {    gridOptions.columnDefs = AgGridColumn.mapChildColumnDefs(this.props);}

    Paso 4: Sincronización de las actualizaciones de las propiedades de la cuadrícula

    Una vez que se inicializa la cuadrícula, debemos realizar un seguimiento de los cambios en React Props para actualizar las opciones de configuración de la cuadrícula de datos. ag-GridImplementa una API para hacer eso. Por ejemplo, si la headerHeightpropiedad cambia, existe un setHeaderHeightmétodo para actualizar la altura de un encabezado.

    React utiliza componentWillReceivePropsel método de ciclo de vida para notificar a un componente sobre los cambios. Aquí es donde colocamos nuestra lógica de actualización:

    export class AgGridReact extends React.Component {    componentWillReceiveProps(nextProps: any) {        const changes = any{};        const changedKeys = Object.keys(nextProps);        changedKeys.forEach((propKey) = {            ...            if (!this.areEquivalent(this.props[propKey], nextProps[propKey])) {                changes[propKey] = {                    previousValue: this.props[propKey],                    currentValue: nextProps[propKey]                };            }        });        AgGrid.ComponentUtil.getEventCallbacks().forEach((funcName: string) = {            if (this.props[funcName] !== nextProps[funcName]) {                changes[funcName] = {                    previousValue: this.props[funcName],                    currentValue: nextProps[funcName]                };            }        });        AgGrid.ComponentUtil.processOnChange(changes, this.gridOptions, this.api, this.columnApi);    }}

    Básicamente, revisamos la lista de ag-Gridpropiedades de configuración y devoluciones de llamadas y verificamos si alguna de ellas ha cambiado. Colocamos todos los cambios en la changesmatriz y luego los procesamos usando processOnChangeel método.

    El método hace dos cosas. Primero, revisa los cambios en React Props y actualiza las propiedades del gridOptionsobjeto. Luego, llama a los métodos de API para notificar a la cuadrícula sobre los cambios:

    export class ComponentUtil {    public static processOnChange(changes, gridOptions, api, ...) {        ...        // reflect the changes in the gridOptions object        ComponentUtil.ARRAY_PROPERTIES            .concat(ComponentUtil.OBJECT_PROPERTIES)            .concat(ComponentUtil.STRING_PROPERTIES)            .forEach(key = {                if (changes[key]) {                    gridOptions[key] = changes[key].currentValue;                }            });        ...        // notify Grid about the changes in header height        if (changes.headerHeight) {            api.setHeaderHeight(changes.headerHeight.currentValue);        }        // notify Grid about the changes in page size        if (changes.paginationPageSize) {            api.paginationSetPageSize(changes.paginationPageSize.currentValue);        }        ...    }}

    Paso 5: Exponer la API

    La interacción con la cuadrícula de React en tiempo de ejecución se realiza a través de la API de cuadrícula. Es posible que desee ajustar el tamaño de las columnas, establecer nuevas fuentes de datos, obtener una lista de todas las filas seleccionadas, etc. Cuando se inicia la cuadrícula de datos de JavaScript, adjunta el apiobjeto al objeto de opciones de cuadrícula. Para exponer este objeto, lo asignamos a la instancia del componente:

    export class AgGridReact extends React.Component {    componentDidMount() {        ...        new AgGrid.Grid(this.eGridDiv, this.gridOptions, gridParams);        this.api = this.gridOptions.api;        this.columnApi = this.gridOptions.columnApi;    }}

    Y eso es todo.

    Conclusión

    En este tutorial, aprendimos cómo adaptar una biblioteca de JavaScript básica para que funcione dentro del marco React.

    Para obtener más información sobre este tema, puede consultar la documentación oficial de React en “Integración con otras bibliotecas” .

    SUSCRÍBETE A NUESTRO BOLETÍN 
    No te pierdas de nuestro contenido ni de ninguna de nuestras guías para que puedas avanzar en los juegos que más te gustan.

    Deja una respuesta

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

    Subir

    Este sitio web utiliza cookies para mejorar tu experiencia mientras navegas por él. Este sitio web utiliza cookies para mejorar tu experiencia de usuario. Al continuar navegando, aceptas su uso. Mas informacion