{"id":233578,"date":"2023-02-17T10:29:00","date_gmt":"2023-02-17T07:29:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=233578"},"modified":"2022-11-11T00:26:42","modified_gmt":"2022-11-10T21:26:42","slug":"crie-um-bloco-gutenberg-personalizado-parte-7-crie-seus-proprios-componentes-personalizados","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pt-pt\/crie-um-bloco-gutenberg-personalizado-parte-7-crie-seus-proprios-componentes-personalizados\/","title":{"rendered":"Crie um bloco Gutenberg personalizado &#8211; Parte 7: crie seus pr\u00f3prios componentes personalizados"},"content":{"rendered":"\n<p>At\u00e9 agora, nesta s\u00e9rie de tutoriais, escrevemos todo o c\u00f3digo dentro <code>registerBlockType()<\/code>da <code>edit<\/code>fun\u00e7\u00e3o do. \u00c9 totalmente poss\u00edvel e geralmente recomendado atribuir a edi\u00e7\u00e3o a um componente separado. Ao fazer isso, podemos utilizar funcionalidades como o estado do componente e os m\u00e9todos do ciclo de vida. Tamb\u00e9m \u00e9 muito mais limpo, leg\u00edvel e fornece c\u00f3digo reutiliz\u00e1vel!<\/p>\n<p>Se voc\u00ea n\u00e3o estiver familiarizado com a cria\u00e7\u00e3o de componentes do React ou quais s\u00e3o os m\u00e9todos de estado e ciclo de vida, recomendo ler primeiro <a href=\"https:\/\/reactjs.org\/docs\/state-and-lifecycle.html\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">o guia oficial do React sobre este t\u00f3pico<\/a>.<\/p>\n<h2>Definindo um componente de classe para<code>edit<\/code><\/h2>\n<p>Voc\u00ea pode definir um componente como uma fun\u00e7\u00e3o ou uma classe. Com um componente de classe, voc\u00ea pode usar funcionalidades como, por exemplo, m\u00e9todos de estado e ciclo de vida. No entanto, nas vers\u00f5es mais recentes do React (16+), voc\u00ea pode usar ganchos do React para simular m\u00e9todos de estado e ciclo de vida dentro de componentes de fun\u00e7\u00e3o. Mas neste tutorial vamos nos concentrar na cria\u00e7\u00e3o de um componente de classe. O que criamos at\u00e9 agora nesta s\u00e9rie, &quot;inline&quot; em <code>registerBlockType()<\/code>for <code>edit<\/code>e <code>save<\/code>, s\u00e3o componentes de fun\u00e7\u00e3o.<\/p>\n<p>Para definir um componente de classe, estendemos o WordPress&#8217; <code>Component<\/code>(no <code>wp.element<\/code>pacote), exatamente como voc\u00ea estenderia um componente de classe para <code>React.Component<\/code>.<\/p>\n<p>Tenha em mente que seu componente de classe deve incluir a fun\u00e7\u00e3o <code>render()<\/code>. E por causa de como o Javascript funciona sua classe deve ser definida antes de sua <code>registerBlockType()<\/code>chamada (escreva seu componente de classe primeiro no arquivo, e mantenha <code>registerBlockType()<\/code>depois dele. Mais adiante neste post vamos aprender como separar componentes em arquivos separados, exportar e incluir eles).<\/p>\n<p>Resumindo, assim:<\/p>\n<pre><code>const { registerBlockType } = wp.blocks;\nconst { Component } = wp.element;\n\u00a0\nclass FirstBlockEdit extends Component {\n    render() {\n        const { attributes, setAttributes } = this.props;\n        return ...\n    }\n}\n\u00a0\nregisterBlockType('awp\/firstblock', {\n    title: 'My first block',\n    edit: FirstBlockEdit,\n    save: (props) =&gt; { \n        return ...\n    }\n});<\/code><\/pre>\n<p>Os adere\u00e7os de <code>edit<\/code>s\u00e3o aplicados automaticamente ao nosso componente. N\u00e3o esque\u00e7a que um componente de classe que voc\u00ea precisa referenciar adere\u00e7os com <code>this.props<\/code>. \u00c9 comum no n\u00facleo do WordPress Gutenberg usar componentes separados para as <code>edit<\/code>fun\u00e7\u00f5es, pois eles geralmente cont\u00eam muito mais c\u00f3digo. A <code>save<\/code>fun\u00e7\u00e3o muitas vezes pode ser deixada a <code>registerBlockType()<\/code>menos que contenha muito c\u00f3digo tamb\u00e9m.<\/p>\n<p>Ao fazer isso, agora voc\u00ea pode escrever seu componente como faria com o React. Voc\u00ea pode adicionar fun\u00e7\u00f5es, construtores, m\u00e9todos de estado e de ciclo de vida.<\/p>\n<p>Este \u00e9 o c\u00f3digo que acabamos na \u00faltima etapa, convertido em um componente de classe:<\/p>\n<pre><code>const { registerBlockType } = wp.blocks;\nconst { Component } = wp.element;\nconst { RichText, InspectorControls, BlockControls, AlignmentToolbar } = wp.blockEditor;\nconst { ToggleControl, PanelBody, PanelRow, CheckboxControl, SelectControl, ColorPicker, Toolbar, IconButton } = wp.components;\n\u00a0\nclass FirstBlockEdit extends Component {\n\u00a0\n    render() {\n        const { attributes, setAttributes } = this.props;\n        const alignmentClass = (attributes.textAlignment != null)? 'has-text-align-' + attributes.textAlignment: '';\n\u00a0\n        return (&lt;div className={alignmentClass}&gt;\n                &lt;InspectorControls&gt;\n                    &lt;PanelBody\n                        title=\"Most awesome settings ever\"\n                        initialOpen={true}\n                    &gt;\n                        &lt;PanelRow&gt;\n                            &lt;ToggleControl\n                                label=\"Toggle me\"\n                                checked={attributes.toggle}\n                                onChange={(newval) =&gt; setAttributes({ toggle: newval })}\n                            \/&gt;\n                        &lt;\/PanelRow&gt;\n                        &lt;PanelRow&gt;\n                            &lt;SelectControl\n                                label=\"What's your favorite animal?\"\n                                value={attributes.favoriteAnimal}\n                                options={[\n                                    {label: \"Dogs\", value: 'dogs'},\n                                    {label: \"Cats\", value: 'cats'},\n                                    {label: \"Something else\", value: 'weird_one'},\n                                ]}\n                                onChange={(newval) =&gt; setAttributes({ favoriteAnimal: newval })}\n                            \/&gt;\n                        &lt;\/PanelRow&gt;\n                        &lt;PanelRow&gt;\n                            &lt;ColorPicker\n                                color={attributes.favoriteColor}\n                                onChangeComplete={(newval) =&gt; setAttributes({ favoriteColor: newval.hex })}\n                                disableAlpha\n                            \/&gt;\n                        &lt;\/PanelRow&gt;\n                        &lt;PanelRow&gt;\n                            &lt;CheckboxControl\n                                label=\"Activate lasers?\"\n                                checked={attributes.activateLasers}\n                                onChange={(newval) =&gt; setAttributes({ activateLasers: newval })}\n                            \/&gt;\n                        &lt;\/PanelRow&gt;\n                    &lt;\/PanelBody&gt;\n                &lt;\/InspectorControls&gt;\n                &lt;BlockControls&gt;\n                    &lt;AlignmentToolbar\n                        value={attributes.textAlignment}\n                        onChange={(newalign) =&gt; setAttributes({ textAlignment: newalign })}\n                    \/&gt;\n                    &lt;Toolbar&gt;\n                        &lt;IconButton\n                            label=\"My very own custom button\"\n                            icon=\"edit\"\n                            className=\"my-custom-button\"\n                            onClick={() =&gt; console.log('pressed button')}\n                        \/&gt;\n                    &lt;\/Toolbar&gt;\n                &lt;\/BlockControls&gt;\n                &lt;RichText \n                    tagName=\"h2\"\n                    placeholder=\"Write your heading here\"\n                    value={attributes.myRichHeading}\n                    onChange={(newtext) =&gt; setAttributes({ myRichHeading: newtext })}\n                \/&gt;\n                &lt;RichText\n                    tagName=\"p\"\n                    placeholder=\"Write your paragraph here\"\n                    value={attributes.myRichText}\n                    onChange={(newtext) =&gt; setAttributes({ myRichText: newtext })}\n                \/&gt;\n            &lt;\/div&gt;\n        );\n    }\n}\n\u00a0\nregisterBlockType('awp\/firstblock', {\n    title: 'My first block',\n    category: 'common',\n    icon: 'smiley',\n    description: 'Learning in progress',\n    keywords: ['example', 'test'],\n    attributes: {\n        myRichHeading: {\n            type: 'string',\n        },\n        myRichText: {\n            type: 'string',\n            source: 'html',\n            selector: 'p'\n        },\n        textAlignment: {\n            type: 'string',\n        },\n        toggle: {\n            type: 'boolean',\n            default: true\n        },\n        favoriteAnimal: {\n            type: 'string',\n            default: 'dogs'\n        },\n        favoriteColor: {\n            type: 'string',\n            default: '#DDDDDD'\n        },\n        activateLasers: {\n            type: 'boolean',\n            default: false\n        },\n    },\n    supports: {\n        align: ['wide', 'full']\n    },\n    edit: FirstBlockEdit,\n    save: (props) =&gt; { \n        const { attributes } = props;\n\u00a0\n        const alignmentClass = (attributes.textAlignment != null)? 'has-text-align-' + attributes.textAlignment: '';\n\u00a0\n        return (&lt;div className={alignmentClass}&gt;\n                &lt;RichText.Content \n                    tagName=\"h2\"\n                    value={attributes.myRichHeading}\n                \/&gt;\n                &lt;RichText.Content \n                    tagName=\"p\"\n                    value={attributes.myRichText}\n                \/&gt;\n                {attributes.activateLasers &amp;&amp; \n                    &lt;div className=\"lasers\"&gt;Lasers activated&lt;\/div&gt;\n                }\n            &lt;\/div&gt;\n        );\n    }\n});<\/code><\/pre>\n<p>Se voc\u00ea desestruturado <code>attributes<\/code>e <code>setAttributes<\/code>de props como fizemos, tudo o que voc\u00ea precisa mudar ao passar para um componente de classe separado \u00e9 mudar uma linha; <code>#9<\/code>de <code>props<\/code>para <code>this.props<\/code>. Todo o c\u00f3digo funcionar\u00e1 como antes, sem corrigir mais nada. Essa \u00e9 a beleza da desestrutura\u00e7\u00e3o. Se voc\u00ea n\u00e3o desestruturar e se referir <code>props.attributes<\/code>diretamente, por exemplo, voc\u00ea precisaria adicionar <code>this.<\/code>na frente de todas as refer\u00eancias individuais <code>attributes<\/code>e em todos os <code>setAttributes<\/code>lugares.<\/p>\n<p>Vamos come\u00e7ar a fazer coisas que agora podemos fazer com um componente de classe!<\/p>\n<h2>Definindo fun\u00e7\u00f5es e<code>this<\/code><\/h2>\n<p>Concedido, sim, voc\u00ea pode definir fun\u00e7\u00f5es de dentro do <code>edit<\/code>componente de fun\u00e7\u00e3o, antes de chamar <code>return<\/code>. Mas, pessoalmente, sempre preferi separar a funcionalidade pela l\u00f3gica. Acho melhor separar fun\u00e7\u00f5es para fins l\u00f3gicos e outros fora da fun\u00e7\u00e3o respons\u00e1vel por renderizar a sa\u00edda. Algumas pessoas tamb\u00e9m preferem chamar fun\u00e7\u00f5es em eventos, em vez de faz\u00ea-las inline como fizemos at\u00e9 agora (<code>setAttributes()<\/code>por <code>onChange<\/code>exemplo).<\/p>\n<p>A partir de agora, nosso c\u00f3digo tem duas coisas que podem ser ben\u00e9ficas para mudar para fun\u00e7\u00f5es; <code>InspectorControls<\/code>e <code>BlockControls<\/code>. Isso reduzir\u00e1 nosso <code>return<\/code>consideravelmente e tornar\u00e1 nosso c\u00f3digo mais f\u00e1cil de ler.<\/p>\n<p>Definimos duas fun\u00e7\u00f5es que retornam o <code>InspectorControls<\/code>bloco inteiro e o <code>BlockControls<\/code>bloco inteiro. Usando as fun\u00e7\u00f5es de seta (<code>functionName =() =&gt; { ... }<\/code>) temos acesso total <code>this<\/code>para obter adere\u00e7os. Se voc\u00ea n\u00e3o fez a \u00faltima parte da etapa 1 \u2013 configurando o Babel com as sintaxes mais recentes, voc\u00ea receber\u00e1 erros de compila\u00e7\u00e3o. Voc\u00ea teria que recorrer \u00e0 cria\u00e7\u00e3o de um construtor e vincula\u00e7\u00e3o <code>this<\/code>para cada fun\u00e7\u00e3o. Voc\u00ea pode ler mais sobre manipula\u00e7\u00e3o <code>this<\/code>no in\u00edcio da <a href=\"https:\/\/reactjs.org\/docs\/faq-functions.html\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">p\u00e1gina de FAQ do React<\/a>.<\/p>\n<p>Lembre-se tamb\u00e9m que por estarmos em uma classe agora voc\u00ea precisa chamar todas as suas fun\u00e7\u00f5es com <code>this.<\/code>na frente.<\/p>\n<pre><code>class FirstBlockEdit extends Component {\n\u00a0\n    getInspectorControls =() =&gt; {\n        const { attributes, setAttributes } = this.props;\n\u00a0\n        return (&lt;InspectorControls&gt;\n                ...\n            &lt;\/InspectorControls&gt;\n        );\n    }\n\u00a0\n    getBlockControls = () =&gt; {\n        const { attributes, setAttributes } = this.props;\n\u00a0\n        return (&lt;BlockControls&gt;\n                ...\n            &lt;\/BlockControls&gt;\n        );\n    }\n\u00a0\n    render() {\n        const { attributes, setAttributes } = this.props;\n        const alignmentClass = (attributes.textAlignment != null)? 'has-text-align-' + attributes.textAlignment: '';\n\u00a0\n        return ([\n            this.getInspectorControls(),\n            this.getBlockControls(),\n            &lt;div className={alignmentClass}&gt;\n                &lt;RichText \n                    tagName=\"h2\"\n                    placeholder=\"Write your heading here\"\n                    value={attributes.myRichHeading}\n                    onChange={(newtext) =&gt; setAttributes({ myRichHeading: newtext })}\n                \/&gt;\n                &lt;RichText\n                    tagName=\"p\"\n                    placeholder=\"Write your paragraph here\"\n                    value={attributes.myRichText}\n                    onChange={(newtext) =&gt; setAttributes({ myRichText: newtext })}\n                \/&gt;\n            &lt;\/div&gt;\n        ]);\n    }\n}<\/code><\/pre>\n<p>Observe que exclu\u00ed o conte\u00fado real de <code>InspectorControls<\/code>e <code>BlockControls<\/code>para manter o c\u00f3digo mais curto. Nada em seu c\u00f3digo precisa mudar.<\/p>\n<p>Tamb\u00e9m estamos utilizando o fato de que a <code>return<\/code>instru\u00e7\u00e3o tamb\u00e9m pode retornar um array. Tudo no array ser\u00e1 renderizado normalmente na ordem em que estiver. Isso facilita a chamada de fun\u00e7\u00f5es diretamente dentro da <code>return<\/code>instru\u00e7\u00e3o.<\/p>\n<p>Obviamente, voc\u00ea tamb\u00e9m pode definir m\u00e9todos de ciclo de vida, como <code>componentDidMount()<\/code>. N\u00e3o h\u00e1 diferen\u00e7a em fazer isso nos componentes do Gutenberg do que no React.<\/p>\n<h2>Construtor e estado de uso<\/h2>\n<p>Vamos tentar implementar o estado em nosso componente. Tenha em mente que o estado \u00e9 apenas algo armazenado temporariamente em nosso componente de classe e n\u00e3o \u00e9 salvo em nenhum lugar \u2013 como em atributos. \u00c9 apenas para manter o controle \u2013 bem \u2013 do estado do seu componente. Os usos comuns de state s\u00e3o usar state como um sinalizador de status enquanto aguarda o retorno de uma chamada ass\u00edncrona, mantendo a pontua\u00e7\u00e3o de algo tempor\u00e1rio antes de salv\u00e1-lo em um atributo ou implementando &quot;modos de visualiza\u00e7\u00e3o\/edi\u00e7\u00e3o&quot; do bloco.<\/p>\n<p>Voc\u00ea se refere ao estado e ao estado de atualiza\u00e7\u00e3o assim como no React; com <code>this.state<\/code>e <code>setState()<\/code>. Normalmente voc\u00ea inicializaria o estado no construtor. E quanto a definir um construtor \u2013 \u00e9 exatamente como no React \u2013 n\u00e3o esque\u00e7a de passar <code>props<\/code>e fazer <code>super(props)<\/code>tamb\u00e9m. Resumidamente:<\/p>\n<pre><code>class FirstBlockEdit extends Component {\n    constructor(props) {\n        super(props);\n\u00a0\n        this.state = {\n            example: 1\n        }\n    }\n\u00a0\n    render() {\n        this.setState({ example: 2 });\n        console.log(this.state.example);\n        ...<\/code><\/pre>\n<h3>Alternador de edi\u00e7\u00e3o\/visualiza\u00e7\u00e3o do modo de bloco<\/h3>\n<p>Vamos usar o que aprendemos na etapa anterior em Barras de ferramentas para criar um &#8220;alterador de modo&quot; para nosso bloco. Implementamos uma barra de ferramentas com um bot\u00e3o que alterna o estado entre o modo de visualiza\u00e7\u00e3o e edi\u00e7\u00e3o. No modo de edi\u00e7\u00e3o, o bloco obt\u00e9m os dois componentes RichText como de costume. Mas ao mudar para o modo de visualiza\u00e7\u00e3o, desativamos a edi\u00e7\u00e3o e renderizamos a sa\u00edda do bloco.<\/p>\n<p>Primeiro criamos um construtor e configuramos o estado com uma propriedade booleana; <code>editMode<\/code>que come\u00e7a como <code>true<\/code>. O <code>super(props)<\/code>\u00e9 necess\u00e1rio ao definir um construtor em um componente React baseado em classe.<\/p>\n<pre><code>class FirstBlockEdit extends Component {\n    constructor(props) {\n        super(props);\n        this.state = {\n            editMode: true\n        }\n    }\n    ...<\/code><\/pre>\n<p>Em nossa fun\u00e7\u00e3o de sa\u00edda das barras de ferramentas, alteramos o bot\u00e3o personalizado que criamos anteriormente (que apenas <code>console.log<\/code>algo ao clicar nele). Em sua <code>onClick<\/code>prop n\u00f3s chamamos <code>setState()<\/code>e negamos o <code>editMode<\/code>valor booleano atual. Para facilitar a compreens\u00e3o do usu\u00e1rio, alternamos tamb\u00e9m entre o \u00edcone e o r\u00f3tulo do bot\u00e3o. Por exemplo, quando o modo de visualiza\u00e7\u00e3o est\u00e1 ativo, o bot\u00e3o mostra o r\u00f3tulo &#8220;Editar&#8221; e um \u00edcone de l\u00e1pis que \u00e9 comumente aceito como edi\u00e7\u00e3o.<\/p>\n<pre><code>getBlockControls = () =&gt; {\n    const { attributes, setAttributes } = this.props;\n    return (&lt;BlockControls&gt;\n            &lt;AlignmentToolbar\n                value={attributes.textAlignment}\n                onChange={(newalign) =&gt; setAttributes({ textAlignment: newalign })}\n            \/&gt;\n            &lt;Toolbar&gt;\n                &lt;IconButton\n                    label={ this.state.editMode? \"Preview\": \"Edit\" }\n                    icon={ this.state.editMode? \"format-image\": \"edit\" }\n                    onClick={() =&gt; this.setState({ editMode: !this.state.editMode })}\n                \/&gt;\n            &lt;\/Toolbar&gt;\n        &lt;\/BlockControls&gt;\n    );\n}<\/code><\/pre>\n<p>E, finalmente, dentro do m\u00e9todo render principal do nosso bloco, podemos fazer o que quisermos. Esta parte \u00e9 realmente com voc\u00ea &#8211; voc\u00ea faz o mesmo que fizemos com o r\u00f3tulo e o \u00edcone no bot\u00e3o acima. Adicionamos dois blocos de sa\u00edda, um if <code>this.state.editMode<\/code>is <code>true<\/code>(que devem ser os componentes edit\u00e1veis \u200b\u200busuais <code>RichText<\/code>) e outro se for <code>false<\/code>.<\/p>\n<p>Como exemplo estou usando dois componentes do WordPress de <code>wp.components<\/code>; <code>Placeholder<\/code>e <code>Disabled<\/code>para o modo de visualiza\u00e7\u00e3o. O <code>Placeholder<\/code>componente coloca seu bloco em uma bela caixa cinza que deixa bem claro que n\u00e3o \u00e9 edit\u00e1vel. Tenha em mente que ele vem anexado com estilo, portanto, se voc\u00ea deseja uma visualiza\u00e7\u00e3o perfeita, isso pode n\u00e3o ser para voc\u00ea. E eu tamb\u00e9m envolvo tudo dentro de um <code>Disabled<\/code>componente que torna tudo dentro de uneditable, unclicable e unrragable. Esta \u00e9 a nossa nova <code>render()<\/code>fun\u00e7\u00e3o em nosso componente:<\/p>\n<pre><code>const { ..., Fragment } = wp.element;\nconst {... Placeholder, Disabled } = wp.components;  \/\/ Don't forget to add these at the top\n\u00a0\n...\nrender() {\n    const { attributes, setAttributes } = this.props;\n    const alignmentClass = (attributes.textAlignment != null)? 'has-text-align-' + attributes.textAlignment: '';\n\u00a0\n    return ([\n        this.getInspectorControls(),\n        this.getBlockControls(),\n        &lt;div className={alignmentClass}&gt;\n            {this.state.editMode &amp;&amp; \n                &lt;Fragment&gt;\n                    &lt;RichText \n                        tagName=\"h2\"\n                        placeholder=\"Write your heading here\"\n                        value={attributes.myRichHeading}\n                        onChange={(newtext) =&gt; setAttributes({ myRichHeading: newtext })}\n                    \/&gt;\n                    &lt;RichText\n                        tagName=\"p\"\n                        placeholder=\"Write your paragraph here\"\n                        value={attributes.myRichText}\n                        onChange={(newtext) =&gt; setAttributes({ myRichText: newtext })}\n                    \/&gt;\n                &lt;\/Fragment&gt;\n            }\n            {!this.state.editMode &amp;&amp; \n                &lt;Placeholder isColumnLayout={true}&gt;\n                    &lt;Disabled&gt;\n                        &lt;RichText.Content \n                            tagName=\"h2\"\n                            value={attributes.myRichHeading}\n                        \/&gt;\n                        &lt;RichText.Content\n                            tagName=\"p\"\n                            value={attributes.myRichText}\n                        \/&gt;\n                    &lt;\/Disabled&gt;\n                &lt;\/Placeholder&gt;\n            }\n        &lt;\/div&gt;\n    ]);\n}\n...<\/code><\/pre>\n<p>Tamb\u00e9m estou usando um componente <code>Fragment<\/code>( <code>wp.element<\/code>pacote) que \u00e9 o mesmo que <code>React.Fragment<\/code>. Se voc\u00ea n\u00e3o estiver familiarizado com ele, n\u00f3s encapsulamos a sa\u00edda dentro dele quando n\u00e3o queremos adicionar wrappers HTML extras desnecess\u00e1rios. Em React tudo deve ter um n\u00f3 raiz. Quando o modo de edi\u00e7\u00e3o est\u00e1 ativo (line <code>#13<\/code>) n\u00f3s produzimos dois <code>RichText<\/code>componentes um ap\u00f3s o outro, ent\u00e3o precisamos de um n\u00f3 raiz ao redor deles.<\/p>\n<p>Quando o modo de pr\u00e9-visualiza\u00e7\u00e3o est\u00e1 ativo (line <code>#29<\/code>), n\u00f3s produzimos os valores dos dois <code>RichText<\/code>componentes. Como fazemos em <code>save<\/code>, usamos <code>RichText.Content<\/code>para retornar seus valores em vez do pequeno editor.<\/p>\n<p>O componente <code>Placeholder<\/code>vem em estilo flex\u00edvel e como padr\u00e3o com linha de dire\u00e7\u00e3o flex\u00edvel. Fornecer <code>true<\/code>no prop o <code>isColumnLayout<\/code>altera para a coluna de dire\u00e7\u00e3o flex\u00edvel (para que tudo seja empilhado). Mas, como mencionado anteriormente \u2013 voc\u00ea pode querer pular este componente e gerar sua visualiza\u00e7\u00e3o exatamente como seria no frontend.<\/p>\n<p>E com isso temos um seletor de visualiza\u00e7\u00e3o\/edi\u00e7\u00e3o do modo de bloco. Obviamente, voc\u00ea pode ajustar o conte\u00fado do &#8220;modo de edi\u00e7\u00e3o&#8221; para mostrar, por exemplo, entradas de controle ou outros enfeites.<\/p>\n<\/p>\n<p>Voc\u00ea pode criar quantos componentes quiser, voc\u00ea n\u00e3o est\u00e1 limitado a apenas ter um para a <code>edit<\/code>fun\u00e7\u00e3o! Basta criar mais componentes e inclu\u00ed-los em uma <code>return<\/code>instru\u00e7\u00e3o. Essa \u00e9 a ideia do React, na verdade \u2013 construir peda\u00e7os de c\u00f3digo encapsulados, possivelmente cada um manipulando seu pr\u00f3prio estado e combin\u00e1-los para fazer UIs complexas.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Fonte de grava\u00e7\u00e3o:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/awhitepixel.com\" class=\"external external_icon\">awhitepixel.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Nesta parte em nosso tutorial de bloco do Gutenberg, aprenderemos como mover a fun\u00e7\u00e3o de edi\u00e7\u00e3o do registerBlockType para um componente separado baseado em classe.<\/p>\n","protected":false},"author":1,"featured_media":152941,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[898,898,722,722,837,941,941,1110,806,806,837,846,846,867,867],"tags":[1170],"class_list":["post-233578","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-codigo-2","category-desenvolvedor","category-guia-para-iniciantes","category-gutenberg-8","category-n-a","category-php-8","category-tutoriais","category-wordpress-8","tag-affiai-pt-pt"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/233578","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/comments?post=233578"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/233578\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media\/152941"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media?parent=233578"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/categories?post=233578"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/tags?post=233578"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}