WordPress Gutenberg: Reaccionar componentes en el front-end

10 minutos de lectura

avatar de usuario
iskotaa

Gutenberg todavía es bastante nuevo, pero todavía espero que alguien haya encontrado este problema y haya encontrado una solución.

Utilicé create-guten-block para repetir un proyecto y creé un bloque de prueba. El problema con el que me encuentro es que cuando trato de usar un componente React para modificar el estado en el front-end, no sucede nada. Los componentes se cargan bien a través de save(), pero cuando intenta hacer algo simple como alternar una lista, el front-end no responde a los cambios de estado. También notaré que create-guten-block no carga ningún JS de front-end, así que cambié el javascript compilado para cargarlo en el front-end y aún no he podido hacerlo funcionar.

Aquí hay un código que saqué de Codecademy como un ejemplo fácil para probar. Cuando selecciona un nombre, cambia el texto en sibling.js para mostrar el nombre. El código funciona bien en create-react-app pero no hace nada en el front-end como un bloque en Gutenberg:

bloque.js

import { Parent } from './parent';

// More code here 

save: function( props ) {
    return (
          <div>
              <Parent />
          </div>
     );
 },

padre.js

import React from 'react';
import { Child } from './child';
import { Sibling } from './sibling';

export class Parent extends React.Component {
    constructor(props) {
        super(props);

        this.state = { name: 'Frarthur' };

        this.changeName = this.changeName.bind(this);
    }

    changeName(newName) {
        this.setState({
        name: newName
        });
    }

    render() {
        return (
        <div>
            <Child onChange={this.changeName} />
            <Sibling name={this.state.name} />
        </div>
        );
    }
};

niño.js

import React from 'react';

export class Child extends React.Component {
    constructor(props) {
        super(props);

        this.handleChange = this.handleChange.bind(this);
    }

    handleChange(e) {
        const name = e.target.value;
        this.props.onChange(name);
    }

    render() {
        return (
        <div>
            <select
            id="great-names"
            onChange={this.handleChange}>

                <option value="Frarthur">Frarthur</option>
                <option value="Gromulus">Gromulus</option>
                <option value="Thinkpiece">Thinkpiece</option>
            </select>
        </div>
        );
    }
}

hermano.js

import React from 'react';

export class Sibling extends React.Component {
    render() {
        const name = this.props.name;
        return (
        <div>
            <h1>Hey, my name is {name}!</h1>
            <h2>Don't you think {name} is the prettiest name ever?</h2>
            <h2>Sure am glad that my parents picked {name}!</h2>
        </div>
        );
    }
}

avatar de usuario
snnsnn

Gutenberg es increíble, pero no puedo decir lo mismo de su documentación. Es como cualquier otra documentación de WordPress, demasiado detallada, mal organizada y habladora. Creo que viene con el territorio y los consumidores objetivo.

Me tomó algún tiempo y varias veces el manual para entender qué son los bloques. Los recursos son escasos y la gente suele confundir los bloques con su representación visual en pantalla en el editor.

Dicho esto, comencemos con lo que son los bloques de Gutenberg. Los bloques de Gutenberg son códigos cortos elegantes como este:

<!-- wp:paragraph {"key": "value"} -->
<p>Welcome to the world of blocks.</p>
<!-- /wp:paragraph -->

El editor convierte estos códigos abreviados en componentes de reacción para una representación visual.

Recuerde los códigos cortos como este aquí, que podría convertirse en una representación visual mediante el complemento tinymce y vería una galería completamente formada y en funcionamiento en la ventana del editor. La idea es la misma, solo que esta vez el editor de Gutenberg presenta códigos abreviados ligeramente diferentes en una representación visual.

Ahora, la confusión surge porque los documentos de WordPress abordan estas representaciones visuales también como bloques. Pero la fuente de verdad para todo el ciclo de renderizado-serialización-análisis-re-renderizado es una y son estos llamados “códigos cortos elegantes”, el resto son diferentes formas y representaciones que toman estos códigos cortos. Digamos, en el contexto del editor, es un componente de reacción renderizado, en el front-end es solo html normal.

Es el elemento de retorno de edit función que determinará cómo aparecerá un bloque en la ventana del editor:

<!-- language: lang-js -->
registerBlockType(«NAMESPACE/BLOCK_NAME», {
    edit: function(props){
        // Should return a react element
    }
})

Es primordial comprender el ciclo de vida de un bloque para comprenderlo mejor. Vamos a empezar desde el principio:

Cuando hace clic en un icono de bloque en el panel de componentes, el retorno de save La función se representará, serializará e insertará en la página.

<!-- language: lang-js -->
registerBlockType("NAMESPACE/BLOCK_NAME", {
    save: function(props){
       // Should return a react element
    }
})

save la función debe devolver un elemento de reacción, este elemento será representado por reaccionar y serializado por el serializador de bloques e insertado en el contenido de la publicación como un bloquear. Puedes comprobar serializer.js para saber cómo el elemento React se serializó en un bloque1.

<!-- wp:image -->
<figure class="wp-block-image"><img src="https://stackoverflow.com/questions/51771125/source.jpg" alt="" /></figure>
<!-- /wp:image -->

Si es un bloque dinámico, save la función volverá null, por lo que no habrá contenido. El bloque se verá así:

<!-- wp:latest-posts {"postsToShow":4,"displayPostDate":true} /-->

Observe el comentario de cierre automático:

En bloques de gramáticael primero se llama bloque estático (_Block_Balanced_) y el segundo es bloque dinámico (_Block_Void_).

Es importante observar que los bloques estáticos contienen contenido renderizado y un objeto de atributos. Para bloques dinámicos, render_callback debe ser suministrado a register_block_type función durante el registro del bloque.

Así que cuando the_content se solicita, el servidor obtiene the_content y lo pasa por varios filtros antes de responder a la solicitud.

Durante esta fase, los atributos se eliminarán de los bloques estáticos y se devolverá el contenido, ya que los bloques estáticos ya tienen su contenido en sí mismos. Para bloques dinámicos, se invocará render_callback y su valor de retorno se devolverá como contenido de bloque. Eso es lo que quieren decir con de alguna manera completamente isomorfo3 en la documentación. Puedes revisar render_block función en el núcleo de WordPress.

Cuando edite el bloque a través de los elementos visuales de gutenberg, el bloque volverá a pasar por el proceso de serialización y se dibujará una nueva representación visual en la página según los cambios que haya realizado.

<!-- wp:paragraph {"key": "value"} -->
<p>Welcome to the world of blocks.</p>
<!-- /wp:paragraph -->

Una vez que haga clic en el botón publicar, estos datos serializados o datos de fila, como lo indica la documentación, se guardarán en la base de datos.

Digamos que cierras la página después de guardar. La próxima vez que lo abra, el analizador de bloques analizará el bloque guardado y la representación visual se dibujará en la página. Puedes echar un vistazo al analizador.2.

Durante el análisis, el marcado de bloque se validará contra el save función. Si cambiaste la devolución de save función entre dos ediciones, el marcado de bloque previamente guardado no será válido o obsoleto. Puede actualizar el código obsoleto proporcionando una ruta de actualización en la configuración de su bloque en registerBlockType. Sin embargo cambias el edit funciona sin repercusiones ya que controla cómo aparecerán los bloques en la pantalla del editor.

La ruta de actualización es solo una matriz de objetos con funciones y propiedades. Cada elemento de esta matriz verificará el bloque en desuso, según la prioridad, y se migrará si el bloque es compatible con la nueva versión; de lo contrario, se devolverá la versión anterior.

Ahora, en cuanto a su pregunta, cuando solicite una página en el servidor front-end, le enviará un html completamente formado. Entonces, en el frente, lo que obtienes es html estático, no un elemento de reacción.

Entonces, en realidad save la función no tiene nada que ver con la interfaz que no sea crear html estático envuelto en comentarios de bloque <!-- wp:image --><!-- /wp:image -->, que sucede durante la edición de contenido. Nunca se ejecuta ni se consulta al servir the_content en la parte delantera.

Para agregar interactividad, debe escribir código dirigido específicamente al front-end, tal como lo hizo antes de Gutenberg.

Puedes ver the_content en su forma de texto sin formato cambiando a Editor de código en la ventana del editor usando Más herramientas y opciones botón, elipses verticales junto a actualizar botón.

Desde la perspectiva de front-end, no hay diferencia si usa el editor tinymce o el editor Gutenberg o html simple al crear the_content.

Depende de usted poner en cola otro archivo javascript o usar el que puso en cola a través de enqueue_block_assets al registrar bloque.

Para usar React, debe montar su componente en el documento usando ReactDOM. Lo bueno es que Wordpess ya proporciona React y ReactDOM en el espacio global, pero debe indicar la dependencia al poner en cola el script.

  • Disculpas por tomar tanto tiempo para marcar esto como la mejor respuesta. ¡Gracias por ser tan completo!

    – iskotaa

    27 de noviembre de 2019 a las 22:18

  • ¿Puede dar un ejemplo de cómo montar el componente en el documento usando ReactDOM? Tengo un problema similar, en el método de guardar, quiero usar React y capturar eventos como onClick.

    – Ognyán

    2 de diciembre de 2019 a las 8:09

  • @Ognyan Claro. const elemento =

    Hola, mundo

    ; ReactDOM.render(elemento, documento.getElementById(‘raíz’)); Asegúrese de tener un elemento con el atributo id como ‘raíz’ en su archivo html. Tienes una explicación más detallada aquí reactjs.org/docs/rendering-elements.html. Si está utilizando gutenberg con wordpress de la forma habitual, puede que reaccionar no sea una buena idea.

    – snnsnn

    2 de diciembre de 2019 a las 9:19


  • @SnnSnn esto debería ponerse en el save función ? ¡Necesito capturar eventos en la interfaz (donde los usuarios deben hacer clic en un botón), no en el editor!

    – Ognyán

    2 de diciembre de 2019 a las 9:22

  • @Ognyan Si tiene la función de guardar, significa que el contenido del bloque ya se representará en la interfaz, solo use vanilla js o jquery, como lo hizo antes.

    – snnsnn

    2 de diciembre de 2019 a las 9:27

Tengo entendido que Gutenburg solo admite la interactividad en el editor lado de la ecuación. Sí, usted define el vista lado en React, pero esta vista se representa en un marcado estático en el punto en que se guarda la publicación, y luego solo este marcado estático se entrega al cliente (lectores).

El beneficio es que obtienes “representación del lado del servidor” de forma gratuita, y tu cliente no necesita React para ver la publicación. La desventaja es que si desea hacer interactividad del lado del cliente, está fuera del alcance de Gutenburg, y tendrá que encontrar su propio camino.

  • ¡Gracias Bessey! Lo he manejado bien en los últimos tres meses y solo proporciono interactividad de front-end con jQuery. No es ideal, pero ya está en cola por WordPress y funciona.

    – iskotaa

    7 de noviembre de 2018 a las 15:45


  • ¿Puede dar un ejemplo de cómo montar el componente en el documento usando ReactDOM? Tengo un problema similar, en el método de guardar, quiero usar React y capturar eventos como onClick.

    – Ognyán

    2 de diciembre de 2019 a las 7:30

¿Ha sido útil esta solución?