{"id":233903,"date":"2023-02-26T18:33:00","date_gmt":"2023-02-26T15:33:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=233903"},"modified":"2023-02-26T18:35:50","modified_gmt":"2023-02-26T15:35:50","slug":"gutenberg-actualizacion-de-withselect-y-withdispatch-en-react-hooks-useselect-y-usedispatch","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/es\/gutenberg-actualizacion-de-withselect-y-withdispatch-en-react-hooks-useselect-y-usedispatch\/","title":{"rendered":"Gutenberg: Actualizaci\u00f3n de withSelect y withDispatch en React Hooks (useSelect y useDispatch)"},"content":{"rendered":"\n<p>Esta publicaci\u00f3n es una introducci\u00f3n r\u00e1pida a una forma de mantener su c\u00f3digo de Gutenberg a la altura de los est\u00e1ndares actuales mediante el uso de ganchos React. Veremos c\u00f3mo esto es beneficioso, por qu\u00e9 debemos hacerlo y c\u00f3mo.<\/p>\n<h2>\u00bfEh, ganchos?<\/h2>\n<p>Supongo que ya tiene algo de experiencia trabajando con bloques o complementos de Gutenberg un poco m\u00e1s complejos que consultan publicaciones, o recuperan y actualizan metadatos de publicaciones. Y as\u00ed he estado trabajando con <code>[withSelect](https:\/\/developer.wordpress.org\/block-editor\/reference-guides\/packages\/packages-data\/#withSelect)<\/code>y\/o <code>[withDispatch](https:\/\/developer.wordpress.org\/block-editor\/reference-guides\/packages\/packages-data\/#withDispatch)<\/code>. Estos son componentes de orden superior en WordPress que le permiten acceder a las tiendas de WordPress para obtener o enviar informaci\u00f3n que est\u00e1 un poco fuera del bloque &quot;normal&quot; o la edici\u00f3n posterior. Es posible que tambi\u00e9n se haya visto obligado a usar <code>compose<\/code>para combinar su componente con varios componentes de orden superior. Si su c\u00f3digo utiliza estos patrones, no se preocupe, \u00a1funcionan perfectamente bien y seguir\u00e1n funcionando! Pero a medida que avanza la tecnolog\u00eda, podemos hacerlo mejor.<\/p>\n<p>A principios de 2019, <a href=\"https:\/\/reactjs.org\/docs\/hooks-intro.html\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">React lanz\u00f3 ganchos<\/a> (versi\u00f3n 16.8), que le permiten usar el estado sin usar una clase y mejorar otras caracter\u00edsticas que brindan un c\u00f3digo m\u00e1s legible y reutilizable. Por ejemplo, eliminar la necesidad de envolver su c\u00f3digo en componentes de orden superior para acceder a los registros. Y en <a href=\"https:\/\/make.wordpress.org\/core\/2019\/06\/10\/introducing-usedispatch-and-useselect\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">el verano de 2019 le sigui\u00f3 WordPress<\/a>, lanzando ganchos personalizados: <code>[useDispatch](https:\/\/developer.wordpress.org\/block-editor\/reference-guides\/packages\/packages-data\/#useDispatch)<\/code>y <code>[useSelect](https:\/\/developer.wordpress.org\/block-editor\/reference-guides\/packages\/packages-data\/#useSelect)<\/code>.<\/p>\n<p>Los beneficios de los ganchos son muchos. El ejemplo m\u00e1s com\u00fan es permitir usar el estado del componente sin tener que escribir una clase Javascript (<code>useState<\/code>). Pero en mi opini\u00f3n, el mayor beneficio es la reutilizaci\u00f3n. Al eliminar la necesidad de usar patrones como accesorios de representaci\u00f3n y componentes de orden superior, los componentes se pueden escribir en piezas mucho m\u00e1s independientes. \u00a1Otro beneficio de los ganchos es que hace que su c\u00f3digo sea m\u00e1s f\u00e1cil de leer y comprender!<\/p>\n<p>\u00a1Pasemos directamente a algunos ejemplos y veamos c\u00f3mo implementar <code>useSelect<\/code>y <code>useDispatch<\/code>enlazar nuestro c\u00f3digo!<\/p>\n<h2>Implementar<code>useSelect<\/code><\/h2>\n<p>Empecemos por <code>withSelect<\/code>y su correspondiente gancho <code>useSelect<\/code>. Estos se utilizan para obtener accesorios derivados del estado de selectores registrados. Los ejemplos comunes son acceder a los selectores &#8216; <code>core<\/code>&#8216; o &#8216; <code>core\/editor<\/code>&#8216; para realizar consultas de publicaciones (<code>getEntityRecords<\/code>), acceder a la publicaci\u00f3n meta (<code>getEditedPostAttribute<\/code>) o simplemente obtener el tipo de publicaci\u00f3n actual u otra informaci\u00f3n.<\/p>\n<p>Para fines de demostraci\u00f3n, comenzar\u00e9 con un ejemplo simple. Supongamos que tengo un componente de bloque donde tengo un selector de publicaci\u00f3n en alguna parte. Para completar las opciones de publicaci\u00f3n, necesito acceder al registro &#8216; <code>core<\/code>&#8216; y realizar una <code>GetEntityRecords()<\/code>llamada.<\/p>\n<h3>Uso antiguo<code>withSelect<\/code><\/h3>\n<p>Si quiero consultar publicaciones en un bloque, necesitar\u00eda envolver mi componente en <code>withSelect<\/code>. Esto se hace com\u00fanmente en la <code>export<\/code>declaraci\u00f3n.<\/p>\n<p>Tenga en cuenta que este ejemplo de c\u00f3digo no est\u00e1 completo como un bloque funcional real o complemento JS, se ha eliminado para mostrar los conceptos b\u00e1sicos de <code>withSelect<\/code>. Si est\u00e1 buscando ejemplos pr\u00e1cticos de c\u00f3digo, tengo otros art\u00edculos que cubren esto: por ejemplo, <a href=\"https:\/\/wordpress.mediadoma.com\/es\/crear-bloque-de-gutenberg-personalizado-parte-10-obtener-publicaciones-y-componentes-de-orden-superior\/\" title=\"c\u00f3mo implementar bloques con una selecci\u00f3n de publicaci\u00f3n\">c\u00f3mo implementar bloques con una selecci\u00f3n de publicaci\u00f3n<\/a>, o <a href=\"https:\/\/wordpress.mediadoma.com\/es\/como-agregar-metacampos-de-publicacion-a-la-barra-lateral-del-documento-de-gutenberg\/\" title=\"c\u00f3mo agregar meta meta al inspector\">c\u00f3mo agregar meta meta al inspector<\/a>. Esos est\u00e1n escritos con <code>withSelect<\/code>y <code>withDispatch<\/code>, tambi\u00e9n h\u00e1galos, y luego regrese aqu\u00ed para aprender c\u00f3mo transformarlos en ganchos.<\/p>\n<pre><code>const { withSelect } = wp.data;\n\u00a0\nconst AWP_Example_Plugin = ({ somePosts }) =&gt; {\n    console.log(\"Posts from withSelect = \", somePosts);\n    return(\n        &lt;div&gt;\n            ...\n        &lt;\/div&gt;\n    );\n}\n\u00a0\nexport default withSelect( (select) =&gt; {      \n    return {\n        somePosts: select( 'core' ).getEntityRecords( 'postType', 'page' ),\n    };\n}) (AWP_Example_Plugin );<\/code><\/pre>\n<p>Como puede ver en la l\u00ednea <code>#12-16<\/code>, envuelvo mi componente con <code>withSelect<\/code>. Dentro de la funci\u00f3n withSelect puedo acceder a la tienda que quiero y devuelvo una consulta de publicaci\u00f3n en el accesorio &quot; <code>somePosts<\/code>&quot;. Este accesorio estar\u00e1 disponible dentro de mi <code>AWP_Example_Plugin<\/code>componente (como puede ver, lo desestructurar\u00e9 <code>somePosts<\/code>de los accesorios en la l\u00ednea <code>#3<\/code>).<\/p>\n<p>Como se mencion\u00f3 anteriormente, este m\u00e9todo funciona bien y continuar\u00e1 haci\u00e9ndolo. Pero hay varias desventajas con esto. Una es que esto no es muy f\u00e1cil de entender. Claro, este fue un ejemplo muy simple. A primera vista del componente en s\u00ed, no est\u00e1 seguro de d\u00f3nde <code>somePosts<\/code>proviene el accesorio o qu\u00e9 es. Tendr\u00eda que saber buscar la declaraci\u00f3n de exportaci\u00f3n y ver si hay alg\u00fan contenedor. Tambi\u00e9n se siente un poco desarticulado. Hace una gran parte del trabajo importante fuera de su componente, para algo que realmente desea que est\u00e9 disponible dentro de su componente.<\/p>\n<p>Hag\u00e1moslo mejor usando ganchos.<\/p>\n<h3>Convirtiendo en<code>useSelect<\/code><\/h3>\n<p>Convertir a <code>withSelect<\/code>en <code>useSelect<\/code>es tan simple como parece. El primer paso es que podemos definir la variable <code>somePosts<\/code>dentro de nuestro componente, en lugar de afuera por la <code>export<\/code>declaraci\u00f3n. El segundo paso es mover toda la funci\u00f3n que ten\u00edamos <code>withSelect<\/code>en <code>useSelect<\/code>. Y eso es.<\/p>\n<pre><code>const { useSelect } = wp.data;\n\u00a0\nconst AWP_Example_Plugin =() =&gt; {\n    const { somePosts } = useSelect( (select) =&gt; {        \n        return {\n            somePosts: select( 'core' ).getEntityRecords( 'postType', 'page' ),\n        };\n    } );\n    console.log(\"Posts from useSelect = \", somePosts);\n    return(\n        &lt;div&gt;\n            ...\n        &lt;\/div&gt;\n    );\n}\n\u00a0\nexport default AWP_Example_Plugin;<\/code><\/pre>\n<p>El c\u00f3digo anterior proporciona exactamente el mismo resultado que el que tiene <code>withSelect<\/code>. \u00a1La diferencia es que el c\u00f3digo ahora es mucho m\u00e1s comprensible! Ahora podemos ver muy f\u00e1cilmente que la variable <code>somePosts<\/code>est\u00e1 almacenando el resultado de una consulta posterior, justo dentro de nuestro componente.<\/p>\n<p><strong>Nota importante<\/strong>: <code>useSelect<\/code>acepta un segundo par\u00e1metro; una serie de dependencias. Las dependencias son variables que aseguran que solo se ejecuten <code>useSelect<\/code>cuando una de las dependencias (valores de variable) haya cambiado. Este bit es m\u00e1s importante <code>useDispatch<\/code>que aqu\u00ed, por lo que lo explicar\u00e9 con m\u00e1s detalle en la <code>useDispatch<\/code>secci\u00f3n a continuaci\u00f3n.<\/p>\n<h2>Implementar<code>useDispatch<\/code><\/h2>\n<p>Ahora echemos un vistazo a <code>withDispatch<\/code>y su gancho correspondiente <code>useDispatch<\/code>. Se utilizan para enviar accesorios a los registros. Por ejemplo, decirle a Gutenberg que actualice una publicaci\u00f3n meta a trav\u00e9s de &#8216; <code>core\/editor<\/code>&#8216;.<\/p>\n<p>Nuevamente, para fines de demostraci\u00f3n, mis ejemplos de c\u00f3digo no son piezas de c\u00f3digo funcionales completas: ilustran solo las partes relacionadas con estos patrones. En este ejemplo, asumo que tengo un campo de texto que muestra una publicaci\u00f3n meta, y deseo actualizar el valor meta de la publicaci\u00f3n al cambiar.<\/p>\n<h3>Uso antiguo<code>withDispatch<\/code><\/h3>\n<p>Como <code>withDispatch<\/code>es un componente de orden superior, necesitar\u00eda envolver mi componente dentro de esto. Esto se hace com\u00fanmente en la <code>export<\/code>declaraci\u00f3n. Para hacer que el campo de texto para nuestro meta trabajo,<\/p>\n<p>Por ejemplo:<\/p>\n<pre><code>const { withDispatch } = wp.data;\nconst { __ } = wp.i18n;\nconst { PluginDocumentSettingPanel } = wp.editPost;\nconst { TextControl, PanelRow } = wp.components;\nconst AWP_Example_Plugin = ({ setPostMeta }) =&gt; { \n    return(\n        &lt;PluginDocumentSettingPanel title={ __( 'withDispatch Example', 'txtdomain') }&gt;\n            &lt;PanelRow&gt;\n                &lt;TextControl\n                    label={ __( 'Example post meta', 'txtdomain') }\n                    value=\"\"\n                    onChange={ (value) =&gt; setPostMeta( { example_post_meta: value }) }\n                \/&gt;\n            &lt;\/PanelRow&gt;\n        &lt;\/PluginDocumentSettingPanel&gt;\n    );\n}\n\u00a0\nexport default withDispatch( (dispatch) =&gt; {\n    return {\n        setPostMeta( newMeta) {\n            dispatch( 'core\/editor' ).editPost( { meta: newMeta } );\n        }\n    };\n} )( AWP_Example_Plugin );<\/code><\/pre>\n<p>En l\u00ednea <code>#20-26<\/code>, envolvemos el componente dentro <code>withDispatch<\/code>, en el que devolvemos una funci\u00f3n \u00bb <code>setPostMeta<\/code>&quot; que despacha post meta (para actualizarlo). En l\u00ednea <code>#6<\/code>, desestructuramos el accesorio para que podamos usarlo en el <code>onChange<\/code>evento del campo de texto en l\u00ednea <code>#13<\/code>. (Tenga en cuenta que el ejemplo anterior no ser\u00eda funcional porque establecemos el valor del campo de texto en una cadena vac\u00eda. Esto es solo para demostrar c\u00f3mo usar\u00edamos el env\u00edo).<\/p>\n<p>Una vez m\u00e1s, podemos ver que el c\u00f3digo no es tan sencillo de entender. Tendr\u00eda que saber buscar el envoltorio para averiguar de qu\u00e9 <code>setPostMeta<\/code>es o de qu\u00e9 proviene el accesorio &quot; &quot;. \u00a1Hag\u00e1moslo mejor usando ganchos!<\/p>\n<h3>Convirtiendo en<code>useDispatch<\/code><\/h3>\n<p>Cambiar <code>withDispatch<\/code>a <code>useDispatch<\/code>no es tan sencillo como convertir <code>withSelect<\/code>a <code>useSelect<\/code>. Sin embargo, todav\u00eda es bastante f\u00e1cil. Hay dos cosas a tener en cuenta. Una es que <code>useDispatch<\/code>toma el nombre de una tienda como primer par\u00e1metro. Luego acceder\u00edamos a la tienda y llamar\u00edamos a sus funciones disponibles cuando las usemos (por ejemplo, en un <code>onChange<\/code>evento de un campo de texto). En segundo lugar, la matriz de dependencias con <code>useDispatch<\/code>el segundo par\u00e1metro es m\u00e1s importante que con <code>useSelect<\/code>. Puede correr el riesgo de que su c\u00f3digo termine en un bucle eterno si no administra las dependencias correctamente. Solo cuando se cambien las variables de dependencia, el script se volver\u00e1 a ejecutar <code>useDispatch<\/code>.<\/p>\n<p>Por ejemplo:<\/p>\n<pre><code>const { useDispatch } = wp.data;\nconst { __ } = wp.i18n;\nconst { PluginDocumentSettingPanel } = wp.editPost;\nconst { TextControl, PanelRow } = wp.components;\nconst AWP_Example_Plugin =() =&gt; {  \n    const tmpMetaValue = \"\";\n    const { editPost } = useDispatch( 'core\/editor', [ tmpMetaValue ] );\n\u00a0\n    return(\n        &lt;PluginDocumentSettingPanel title={ __( 'useDispatch Example', 'txtdomain') }&gt;\n            &lt;PanelRow&gt;\n                &lt;TextControl\n                    label={ __( 'Example post meta', 'txtdomain') }\n                    value={ tmpMetaValue }\n                    onChange={ (value) =&gt; editPost( { meta: { example_post_meta: value } }) }\n                \/&gt;\n            &lt;\/PanelRow&gt;\n        &lt;\/PluginDocumentSettingPanel&gt;\n    );\n}\n\u00a0\nexport default AWP_Example_Plugin;<\/code><\/pre>\n<p>En l\u00ednea <code>#8<\/code>desestructuramos lo que necesitamos de la tienda &#8216; <code>core\/editor<\/code>&#8216;. Solo estamos interesados \u200b\u200b\u200b\u200ben la <code>editPost<\/code>funci\u00f3n que podemos usar para actualizar la publicaci\u00f3n meta. Como segundo par\u00e1metro <code>useDispatch<\/code>proporcionamos dependencias. En cuanto a un ejemplo de actualizaci\u00f3n de la publicaci\u00f3n meta, usar el valor de la publicaci\u00f3n meta (usando <code>useSelect<\/code>) ser\u00eda perfecto como dependencia. En este ejemplo, lo configur\u00e9 como una variable ficticia. Mire m\u00e1s abajo para ver un ejemplo m\u00e1s completo y realista. Y luego, en <code>#16<\/code>la l\u00ednea del evento del campo de texto <code>onChange<\/code>, llamamos <code>editPost<\/code>para actualizar el meta. \u00a1 Observe la diferencia en esta l\u00ednea con el uso <code>withDispatch<\/code>anterior! Dado que usamos <code>editPost<\/code>directamente en lugar de devolver una funci\u00f3n para actualizar la publicaci\u00f3n meta para nosotros (<code>setPostMeta<\/code>), debemos proporcionar un objeto con<code>meta<\/code>como clave y luego un objeto con la publicaci\u00f3n meta que queremos actualizar. Tenemos una especie de divisi\u00f3n del <code>withDispatch<\/code>c\u00f3digo en partes.<\/p>\n<p>A\u00fan as\u00ed, el uso <code>useDispatch<\/code>hace que el c\u00f3digo sea mucho m\u00e1s legible y comprensible. No se agrega m\u00e1s c\u00f3digo fuera de nuestro componente que necesitamos usar dentro.<\/p>\n<h2>Un ejemplo m\u00e1s completo y eliminando la necesidad de<code>compose<\/code><\/h2>\n<p>Lo m\u00e1s probable es que si est\u00e1 utilizando <code>withDispatch<\/code>, tambi\u00e9n necesitar\u00e1 <code>withSelect<\/code>ese componente. En los ejemplos para convertir a <code>useDispatch<\/code>los anteriores, estamos actualizando un metavalor de publicaci\u00f3n. Pero para que el campo de texto funcione correctamente (y tambi\u00e9n muestre el valor actual), tambi\u00e9n necesitar\u00edamos obtener el valor meta de la publicaci\u00f3n.<\/p>\n<p>Si necesita usar m\u00faltiples componentes de orden superior envueltos alrededor de su componente, lo m\u00e1s probable es que use otra funci\u00f3n de Gutenberg; <code>[compose](https:\/\/developer.wordpress.org\/block-editor\/reference-guides\/packages\/packages-compose\/)<\/code>. Es una funci\u00f3n \u00fatil para combinar m\u00faltiples componentes de orden superior en un componente de orden superior que puede envolver su componente.<\/p>\n<p>Veamos un ejemplo m\u00e1s completo de un componente que obtiene un metavalor de publicaci\u00f3n en un campo de texto y se actualiza cuando se cambia su valor. Comenzamos con c\u00f3mo tendr\u00edamos que hacerlo usando <code>withSelect<\/code>y <code>withDispatch<\/code>(y por lo tanto tambi\u00e9n <code>compose<\/code>).<\/p>\n<h3>Usando <code>withSelect<\/code>, <code>withDispatch<\/code>y<code>compose<\/code><\/h3>\n<pre><code>const { __ } = wp.i18n;\nconst { compose } = wp.compose;\nconst { withSelect, withDispatch } = wp.data;\nconst { PluginDocumentSettingPanel } = wp.editPost;\nconst { TextControl, PanelRow } = wp.components;\n\u00a0\nconst AWP_Example_Plugin = ({ postMeta, setPostMeta }) =&gt; {\n    return(\n        &lt;PluginDocumentSettingPanel title={ __( 'withSelect and withDispatch Example', 'txtdomain') }&gt;\n            &lt;PanelRow&gt;\n                &lt;TextControl\n                    label={ __( 'Example post meta', 'txtdomain') }\n                    value={ postMeta.example_post_meta }\n                    onChange={ (value) =&gt; setPostMeta( { example_post_meta: value }) }\n                \/&gt;\n            &lt;\/PanelRow&gt;\n        &lt;\/PluginDocumentSettingPanel&gt;\n    );\n}\n\u00a0\nexport default compose( [\n    withSelect( (select) =&gt; {     \n        return {\n            postMeta: select( 'core\/editor' ).getEditedPostAttribute( 'meta' ),\n        };\n    } ),\n    withDispatch( (dispatch) =&gt; {\n        return {\n            setPostMeta( newMeta) {\n                dispatch( 'core\/editor' ).editPost( { meta: newMeta } );\n            }\n        };\n    }) ] )( AWP_Example_Plugin );<\/code><\/pre>\n<p>En l\u00ednea <code>#21-34<\/code>, componemos <code>withSelect<\/code>y <code>withDispatch<\/code>los envolvemos alrededor de nuestro componente. <code>postMeta<\/code>from <code>withSelect<\/code>y <code>setPostMeta<\/code>from <code>withDispatch<\/code>ahora est\u00e1n disponibles en nuestro componente como accesorios. Los desestructuramos en l\u00ednea <code>#7<\/code>y los usamos en <code>#13<\/code>y <code>#14<\/code>.<\/p>\n<p>Como puede ver, el c\u00f3digo necesario fuera de nuestro componente es m\u00e1s largo que el propio componente. No s\u00e9 ustedes, pero para m\u00ed se siente un poco inconexo. Los desarrolladores pueden comenzar a leer este c\u00f3digo desde la parte superior, sin ver la parte inferior, y comenzar a preguntarse de d\u00f3nde <code>postMeta<\/code>y de d\u00f3nde <code>setPostMeta<\/code>provienen; parecen estar m\u00e1gicamente disponibles. Para m\u00ed esto es muy poco intuitivo.<\/p>\n<p>Veamos c\u00f3mo convertir\u00edamos el ejemplo anterior en ganchos.<\/p>\n<h3>usando <code>useSelect<\/code>y<code>useDispatch<\/code><\/h3>\n<pre><code>const { __ } = wp.i18n;\nconst { useSelect, useDispatch } = wp.data;\nconst { PluginDocumentSettingPanel } = wp.editPost;\nconst { TextControl, PanelRow } = wp.components;\n\u00a0\nconst AWP_Example_Plugin = () =&gt; {\n    const { postMeta } = useSelect( (select) =&gt; {     \n        return {\n            postMeta: select( 'core\/editor' ).getEditedPostAttribute( 'meta' ),\n        };\n    } );\n    const { editPost } = useDispatch( 'core\/editor', [ postMeta.example_post_meta ] );\n\u00a0\n    return(\n        &lt;PluginDocumentSettingPanel title={ __( 'useSelect and useDispatch Example', 'txtdomain') }&gt;\n            &lt;PanelRow&gt;\n                &lt;TextControl\n                    label={ __( 'Example post meta', 'txtdomain') }\n                    value={ postMeta.example_post_meta }\n                    onChange={ (value) =&gt; editPost( { meta: { example_post_meta: value } }) }\n                \/&gt;\n            &lt;\/PanelRow&gt;\n        &lt;\/PluginDocumentSettingPanel&gt;\n    );\n}\n\u00a0\nexport default AWP_Example_Plugin;<\/code><\/pre>\n<p>\u00a1\u00bfQu\u00e9 tan hermoso y legible es eso?! Podemos ver de inmediato en nuestro componente de d\u00f3nde <code>postMeta<\/code>se obtiene y c\u00f3mo accedemos a <code>editPost<\/code>. Nuestro componente tambi\u00e9n se volvi\u00f3 mucho m\u00e1s f\u00e1cil de reutilizar.<\/p>\n<p>Tenga en cuenta que en <code>useDispatch<\/code>l\u00ednea <code>#12<\/code>agregamos el postmeta que estamos actualizando como dependencia (<code>postMeta.example_post_meta<\/code>). Si tuviera que mantener varias metavariables de publicaci\u00f3n actualizadas en este componente, tendr\u00eda que agregar cada una como una dependencia para asegurarse de que el env\u00edo se ejecute (en realidad guardando la metadataci\u00f3n de publicaci\u00f3n) cuando cambie el valor de una de ellas.<\/p>\n<p>Espero que esto haya sido informativo y \u00fatil para alguien por ah\u00ed. Todav\u00eda no estoy familiarizado con los ganchos, pero al ver los beneficios de usarlos, \u00a1no voy a dar marcha atr\u00e1s!<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Fuente de grabaci\u00f3n:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/awhitepixel.com\" class=\"external external_icon\">awhitepixel.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Una introducci\u00f3n al uso de los ganchos React useSelect y useDispatch. Veremos c\u00f3mo esto es beneficioso, por qu\u00e9 debemos hacerlo y exactamente c\u00f3mo.<\/p>\n","protected":false},"author":1,"featured_media":151604,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[810,935,935,1110,810,840,840,861,861],"tags":[1172],"class_list":["post-233903","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-complementos","category-gutenberg-2","category-n-a","category-tutoriales","category-wordpress-2","tag-affiai-es"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/233903","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/comments?post=233903"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/233903\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media\/151604"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media?parent=233903"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/categories?post=233903"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/tags?post=233903"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}