Categorias
WordPress

Internacionalização com blocos Gutenberg

Se você está acessando o blog pela primeira vez esse post faz parte de uma série de posts relacionados na criação de blocos para o novo editor do WordPress Gutenberg. Caso queira conferir os posts anteriores:

Internacionalização dentro da construção de temas é o fator fundamental, nele damos a possibilidade do tema se adaptar a diversos idiomas. Essa regra também se aplica aos nossos blocos, caso queiramos criar um produto que atenda diversos idiomas, precisaremos permitir que toda saída de texto do nosso bloco se a adapte ao idioma do WordPress.

Antes do Gutenberg a internacionalização de texto era feita no back-end através da função wp_localize_script() . Agora com o Gutenberg é possível fazer a internacionalização no front-end, para isso vamos trabalhar como uma biblioteca javascript chamada wp-i18n. Se você já trabalhou com a internacionalização de temas o processo será o mesmo, precisamos especificar uma domínio para nossas String, nada mais é que um id que é adicionado no cabeçalho do nosso tema ou plugin. Após definido nosso domínio (text domain) fazemos a chama de texto da seguinte forma:

__( 'Hello, dear user!', 'my-text-domain' );

Essa função que envolve o texto será responsável por conferir se o tema ou plugin possui tradução para essa string, que será armazenado em um arquivo .pot. Ele pode ser gerado automaticamente por algumas ferramentas. No caso de blocos Gutenberg podemos utilizar o WordPress i18n babel plugin para gerar nosso arquivo .pot.

Para nosso tutorial vamos utilizar os blocos criados nos exercícios anteriores e o resultado será o seguinte:

/** * 1 - Criando primeiro bloco Gutenberg com ES5: parte 04 * - internacionalizacao com blocos gutenberg */ ( function( blocks, element, editor, i18n ) { var el = element.createElement, RichText = editor.RichText; //registrando nosso bloco blocks.registerBlockType( 'fellyph/tutorial-03', { title: i18n.__('Bloco com cadastro de atributo', 'fellyph'), icon: 'smiley', category: 'layout', keywords: [ i18n.__('Tutorial', 'fellyph'), i18n.__('Cadastro', 'fellyph'), i18n.__('Dinâmico', 'fellyph') ], //registrando o tipo de bloco que iremos trabalhar attributes: { content: { type: 'string', source: 'html', selector: 'p', } }, // função responsável por exibir nosso bloco no editor edit: function(props) { var content = props.attributes.content; // função responsável por acompanhar as mudanças do nosso atributo function onChangeContent( newContent ) { props.setAttributes( { content: newContent } ); } // agora retornamos um elemento RichText ao invés de um parâgrafo return el( RichText, { tagName: 'p', className: props.className, onChange: onChangeContent, placeholder: i18n.__('Insira texto aqui', 'fellyph'), value: content, } ); }, save: function(props) { return el( RichText.Content , { tagName: 'p', className: props.className, value: props.attributes.content, } ); }, }); }( window.wp.blocks, window.wp.element, window.wp.editor, window.wp.i18n ) );

Na primeira linha adicionamos uma nova dependência o script i18n, dentro do nosso script trocamos todas as chamadas de strings que serão exibidas para o usuário, no front-end e no editor de nossa aplicação pela função i18n.__() , nela vamos passar o texto original e o text domain para tradução como parâmetros.

Para aumentar a quantidade de texto eu adicionei uma nova propriedade em nosso bloco keywords, ela ajudar na busca de nossos componentes, no caso adicionamos 3 keywords em um array: Tutorial, Cadastro e Dinâmico com isso quando realizamos uma consulta as keywords podem ser um critério para achar o nosso bloco como podemos ver na imagem abaixo:

A keyword ajuda a achar o nosso bloco

O resultado do nosso bloco será praticamente o mesmo, com uma diferença que o nosso texto agora está localizado:

Podemos ver nos detalhes do nosso bloco que estamos carregando o título que cadastramos e no bloco podemos ver o nosso placeholder.

O último passo será criar o nosso arquivo de tradução o .poc, temos duas opções, a primeira seria gerando com software especifico o poedit, caso você queira evitar tooling com Babel e Webpack:

A seguida opção com o pacote nodeJS @wordpress/babel-plugin-makepot, para isso precisamos figuração de nosso projeto com babel e Webpack isso vai demandar um post específico dai entramos na criação de blocos com JSX.

O código completo você irá encontrar em meu github: https://github.com/fellyph/Gutenberg-tutorials/tree/tutoriais/gutenberg-04

Até o próximo post!

Categorias
WordPress

Blocos Gutenberg trabalhando com atributos

Esse post é o terceiro de uma série de posts sobre o blocos Gutenberg. Nesse tutorial vamos abordar como trabalhar com atributos em posts customizados. Nos posts anteriores vimos como registrar o nosso bloco customizado e adicionar um estilo ao nosso markup. Agora vamos entender como os atributos funcionam dentro do WordPress. Caso ainda não viu os posts anteriores você confere aqui:

Atributos

Até o momento, nos posts anteriores, quando registramos o nosso primeiro bloco passamos apenas um paragrafo estático, mas caso queiramos dar a possibilidade para o usuário cadastrar uma informação dinamicamente através do editor como serão os próximos passos? Vimos durante a chamada da função edit podemos receber um objeto com propriedades relacionadas ao nosso bloco e uma dessas informações é a propriedade attributes. Para trabalhar com a edição de conteúdo vamos trabalhar com alguns componentes do WordPress.

Componentes

Os blocos muitas vezes repetem a mesma complexidade, isso nos permite aplicar a reutilização de certos recursos, para simplificar a edição de conteúdo, o core do WordPress tem uma série componentes React que realizam tarefas específicas, mas não se assuste você não precisa aprender React para utilizar esse recursos. Mas meu conselho se você que trabalhar de forma mais produtiva é uma tecnologia que ajuda bastante, mas o foco desse tutorial vamos trabalhar com EcmaScript5, Dentro dos componentes vamos abordar dois componentes:

RichText

Ele irá renderizar para nos um input editável com a possibilidade de inclusa de texto e links. Dentro do componente RichText temos as seguintes propriedades:

  • value: espera um valor do tipo string, será o conteúdo armazenado ate o momento, podendo ser texto ou markup valido.
  • onChange: esse atributo espera uma função, será o callback responsável quando o valor do atributo sofre uma alteração
  • placeholder: O valor do campo quando estiver vazio. isso é válido tanto para o input text ou textarea o valor será o mesmo
  • multiline: Se o bloco irá permitir que o usuário cadastre multiplas linhas quando presionar enter, quando desabilitado o cada enter irá criar um novo bloco.

BlockControls

Quando nosso bloco é renderizado dentro do editor, uma barra de ferramentas é exibida com algumas opções relacionadas ao bloco selecionado, por exemplo, caso queiramos exibir opções de alinhamento de texto ao nosso bloco passamos o elemento responsável por alinhamento. O BlockControls espera o seguinte:

  • icon: slug do dashicon para ser mostrado na barra de controle
  • title: um título será exibido em forma de tooltip para o usuário
  • subscript: Um texto opcional para ser exibido adjacente ao ícone da barra de controle
  • isActive: um booleano para definir se o barra de controle será selecionada ou não por default.

Para esse tutorial vamos registrar dois blocos, primeiro exemplo(script.js) apenas com um richText component e o segundo bloco fazendo o uso do blockControl e richText(script-controls.js).

script.js

/** * 1 - Criando primeiro bloco Gutenberg com ES5: parte 03 * - carregando atributos */ ( function( blocks, element, editor ) { var el = element.createElement, RichText = editor.RichText; //registrando nosso bloco blocks.registerBlockType( 'fellyph/tutorial-03', { title: 'Primeiro bloco Gutenberg: Parte 03', icon: 'smiley', category: 'layout', //registrando o tipo de bloco que iremos trabalhar attributes: { content: { type: 'string', source: 'html', selector: 'p', } }, // função responsável por exibir nosso bloco no editor edit: function(props) { var content = props.attributes.content; // função responsável por acompanhar as mudanças do nosso atributo function onChangeContent( newContent ) { props.setAttributes( { content: newContent } ); } // agora retornamos um elemento RichText ao invés de um parâgrafo return el( RichText, { tagName: 'p', className: props.className, onChange: onChangeContent, value: content, } ); }, save: function(props) { return el( RichText.Content , { tagName: 'p', className: props.className, value: props.attributes.content, } ); }, }); }( window.wp.blocks, window.wp.element, window.wp.editor ) );

Como podemos ver no código acima, vamos ter mais uma dependência a classe editor do WordPress presente no script wp-editor, nela vamos encontrar os componentes relacionados a edição de conteúdo. Próximo passo adicionamos em uma variável nosso RichText, seguindo nosso código dentro do registerBlockType temos algumas alterações, adicionamos uma nova propriedade attributes ele é responsável pela configuração do nosso atributo. Ela merece um post específico só falando sobre

Mas voltando para o nosso tutorial definimos a configuração do atributo content esse nome pode ser qualquer um, por exemplo, “conteúdo”. Para esse atributo passamos um objeto de configuração como o tipo do dado(type), a fonte que iremos receber do editor(source), valores padrões(default) entre outras informações.

Dentro da função do edit, o nosso elemento RichText definimos os atributos tagName, className, onChange, value. Também criamos uma função onChangeContent ela é necessária por conta de um conceito do React de controle de estado, precisamos implementar um controlled component para isso, um resumo bem grosseiro, precisamos conectar o valor do input com o estado do component.

Index.php

Algumas diferenças na implementação do index.php, são o registro de dois blocos e quando registramos nosso script precisar adicionar a dependência ao ‘wp-editor’.

<?php /** * Plugin Name: Gutenberg tutorial * Plugin URI: https://github.com/fellyph/gutenberg-tutorials * Description: Este tutorial ensina como criar um bloco gutenberg https://blog.fellyph.com.br/wordpress-2/criando-seu-proprio-bloco-gutenberg/. * Version: 1.3 * Author: fellyph */ defined( 'ABSPATH' ) || exit; /** * 1 - Criando nosso primeiro bloco: Parte 03 * 1.1 - Adicionando o recurso de cadastrar atributos * 1.2 - Adicionando o bloco com block control */ function meu_primeiro_bloco_gutenberg_parte_03 () { if ( ! function_exists( 'register_block_type' ) ) { // Checamos se temos suporte a função register_block_type antes de tudo. return; } wp_register_script( 'tutorial-03', plugins_url( 'script.js', __FILE__ ), array( 'wp-blocks', 'wp-element', 'wp-editor' ), filemtime( plugin_dir_path( __FILE__ ) . 'script.js' ) ); wp_register_script( 'tutorial-03-alinhamento', plugins_url( 'script-controls.js', __FILE__ ), array( 'wp-blocks', 'wp-element', 'wp-editor' ), filemtime( plugin_dir_path( __FILE__ ) . 'script-controls.js' ) ); wp_register_style( 'style-editor', plugins_url( 'editor-style.css', __FILE__ ), array('wp-edit-blocks'), filemtime( plugin_dir_path( __FILE__ ) . 'editor-style.css' ) ); wp_register_style( 'style-frontend', plugins_url( 'style.css', __FILE__ ), filemtime( plugin_dir_path( __FILE__ ) . 'style.css' ) ); register_block_type( 'fellyph/tutorial-03', array( 'style' => 'style-frontend', 'editor_script' => 'tutorial-03', 'editor_style' => 'style-editor' )); register_block_type( 'fellyph/tutorial-03-alinhamento', array( 'style' => 'style-frontend', 'editor_script' => 'tutorial-03-alinhamento', 'editor_style' => 'style-editor' )); } add_action( 'init', 'meu_primeiro_bloco_gutenberg_parte_03' );

Um ponto importante em nosso script, quando registramos um novo id(fellyph/tutorial-03-alinhamento e fellyph/tutorial-03) para nosso bloco precisamos atualizar o nosso seletores CSS:

.wp-block-fellyph-tutorial-03-alinhamento, .wp-block-fellyph-tutorial-03 { background: #12c2e9; border: 3px solid #666; box-shadow: 0 0 0 #666; } .wp-block-fellyph-tutorial-03-alinhamento:hover, .wp-block-fellyph-tutorial-03:hover { transform: rotate3d(0, 0, 0, 0); }

script-controls.js

/** * 1 - Criando primeiro bloco Gutenberg com ES5: parte 03 * - carregando atributos com BlockControls */ ( function( blocks, element, editor ) { var el = element.createElement, RichText = editor.RichText, AlignmentToolbar = editor.AlignmentToolbar, BlockControls = editor.BlockControls; //registrando nosso bloco blocks.registerBlockType( 'fellyph/tutorial-03-alinhamento', { title: 'Bloco com controle de alinhamento', icon: 'welcome-view-site', category: 'layout', //registrando os atributos que iremos trabalhar attributes: { content: { type: 'string', source: 'html', selector: 'p' }, alinhamento: { type: 'string', default: 'none' }, }, // unção responsável por exibir nosso bloco no editor edit: function(props) { var content = props.attributes.content; var alinhamento = props.attributes.alinhamento; // função responsável por acompanhar as mudanças do nosso atributo function onChangeContent( newContent ) { props.setAttributes( { content: newContent } ); } function onChangeAlignment (nextAlign ) { props.setAttributes( { alinhamento: nextAlign } ); } // agora retornamos um array por que estamos utilizando dois componentes return [ el( BlockControls, { key: 'controls' }, el( AlignmentToolbar, { value: alinhamento, onChange: onChangeAlignment }) ), el( RichText, { key: 'richtext', tagName: 'p', style: { textAlign: alinhamento }, className: props.className, onChange: onChangeContent, value: content, placeholder: 'Insira seu nome aqui' } ), ]; }, save: function(props) { return el( RichText.Content , { tagName: 'p', className: props.className, style: { textAlign: props.attributes.alinhamento }, value: props.attributes.content, } ); }, }); }( window.wp.blocks, window.wp.element, window.wp.editor ) );

No código acima temos alguns pontos importantes diferente do primeiro código, em atributos adicionamos um novo valor, “alinhamento” ele será do tipo string e terá um valor padrão ‘none’.

Dentro da função edit adicionamos uma função para acompanhar as mudanças desse componente onChangeAlignment onde atualizamos o valor do atributo referente ao alinhamento.

Agora quando retornamos o nosso bloco utilizamos um array para passar mais de um componente, por que precisamos de um blockControls para passar as configurações necessárias e um RichText para o usuário cadastrar um texto.

Dentro do nosso blockControls podemos também passar uma série de outros componentes relacionados a configurações mas para esse caso vamos utilizar apenas o AlignmentToolbar :

Em seguida conectamos o valor do aligmentToolbar ao nosso RichText, tanto no preview na função edit quando no nosso front-end na função save, definindo o atributo style: { textAlign: alinhamento }.

E esse será o resultado dos dois blocos que criamos aqui:

Exemplo de RichText
bloco utilizando placeholder
Exemplo com BlockControls e AligmentToolbar

O código desse tutorial você irá encontrar no meu git, para cada tutorial estou criando uma branch:

https://github.com/fellyph/Gutenberg-tutorials/tree/tutoriais/gutenberg-03

Qualquer feedback deixe aqui seu comentário e até o próximo tutorial

Referências:

https://wordpress.org/gutenberg/handbook/designers-developers/developers/tutorials/block-tutorial/introducing-attributes-and-editable-fields/

https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-attributes/

https://wordpress.org/gutenberg/handbook/designers-developers/developers/packages/packages-editor/

Categorias
WordPress

Criando seu próprio bloco Gutenberg

Continuando a série sobre o Gutenberg nesse post vamos criar o nosso primeiro bloco Gutenberg, para esse exercício vamos nos basear no repositório oficial do WordPress, lá vamos encontrar uma série de exemplos de como trabalhar com blocos Gutenberg.

No desenvolvimento de blocos temos a possibilidade de criar blocos com EcmaScript 5 e ESNext. Neste tutorial vamos abordar os exemplos com ES5.

Escrevendo o primeiro bloco

Vamos partir do principio mais básico, exibir um bloco estático HTML. Essa função pode ser útil caso desejamos criar uma bloco de assinatura ou contato por exemplo. Nos posts seguintes vamos incrementando essa solução.

Para esse bloco temos dois conceitos importantes, o primeiro ele será adicionado como um plugin é uma técnica recomendada pela documentação, o segundo ponto toda o conteúdo HTML será definido por uma JavaScript. Então com essas premissas vamos ter dois arquivos base em nosso exemplo, o PHP(index.php) que irá inicializar nosso plugin e o Script(primeiro-bloco.js) responsável pelo conteúdo.

index.php

No index.php vamos gerenciar os passos necessários do nosso plugin que irá criar o nosso bloco Gutenberg, nele temos uma atenção especial para duas funções register_block_type e wp_register_script. 

Register_block_type será responsável por registrar o nosso dentro do WordPress como parâmentro ele espera, quais serão os scripts e estilos necessários para executar esse bloco, tanto dentro de editor como para o usuário final no front-end de nossa aplicação.

Wp_register_script será responsável por a tarefa de carregar o script do nosso bloco para o WordPress, assim o WordPress sabe a hora exata de carregar o script e qual serão suas dependências de script dentro da aplicação. Para ficar mais claro vamos ao nosso exemplo:

<?php /** * Plugin Name: Gutenberg tutorial * Plugin URI: https://github.com/fellyph/Gutenberg-tutorials * Description: Este tutorial ensina como criar um bloco Gutenberg https://blog.fellyph.com.br/wordpress-2/criando-seu-proprio-bloco-gutenberg/. * Version: 1.0 * Author: fellyph */ defined( 'ABSPATH' ) || exit; /** * 1 - Criando nosso primeiro bloco * 1.1 - precisamos registrar nosso script para ser adicionado na função register_block * 1.2 - registramos nosso block type passando nosso script */ function meu_primeiro_bloco_gutenberg () { if ( ! function_exists( 'register_block_type' ) ) { // Checamos se temos suporte a função register_block_type antes de tudo. return; } wp_register_script( 'tutorial-gutenberg-01', plugins_url( 'primeiro-bloco.js', __FILE__ ), array( 'wp-blocks', 'wp-element' ), filemtime( plugin_dir_path( __FILE__ ) . 'primeiro-bloco.js' ) ); register_block_type( 'fellyph/tutorial-01', array( 'editor_script' => 'tutorial-gutenberg-01', ) ); } add_action( 'init', 'meu_primeiro_bloco_gutenberg' );

Notem quando registramos nosso script temos duas dependências wp-blocks e wp-element são requisitos mínimos para trabalhar com blocos, para entender mais sobre essas duas dependências:

  • wp-blocks inclui registro de tipos de blocos e mêcanica como os itens são armazenados formulários e funções relacionadas para cada evento específico quando o bloco é salvo ou exibido em nosso front-end
  • wp-element inclui uma camada de abstração pada os blocos Gutenberg, trás a renderização desses elementos do nosso back-end para nosso front-end.

JavaScript do nosso bloco

/** * 1 - primeiro bloco Gutenberg com ES5 */ ( function( blocks, element ) { var el = element.createElement; // criando estilo para nosso editor var blockStyle = { backgroundColor: 'green', color: 'white', padding: '2em', border: '3px solid black' }; //criando estilo para nosso front-end var blockStyleFront = { backgroundColor: 'blue', color: 'white', padding: '2em', border: '3px solid black' }; blocks.registerBlockType( 'fellyph/tutorial-01', { title: 'Primeiro bloco Gutenberg', icon: 'universal-access-alt', category: 'layout', edit: function() { return el( 'p', { style: blockStyle }, 'Este conteúdo será exibido no editor.' ); }, save: function() { return el( 'p', { style: blockStyleFront }, 'Este conteúdo será exibido para o usuário final.' ); }, } ); }( window.wp.blocks, window.wp.element ) );

Lendo nosso código fica evidente a importância de nossas dependências vamos agora passar por alguns pontos chaves. O código Javascript temos o uso de IIFE para garantir que iremos rodar nosso script quando tivemos acesso aos scripts carregados pelo WordPress que estarão disponíveis globalmente por window.wp.blocks e window.wp.element

Dentro de nossa função armazenamos a função createElement responsável por criar nosso markup em uma variável “el” e na sequência criamos dois objetos responsáveis pelo estilo do nosso bloco blockStyle e blockStyleFront.

Com a inicialização de nossas variáveis vamos agora utilizar o wp-blocks, será carregado como blocks dentro do nosso script, assim, chamamos a função blocks.registerBlockType responsável por criar nosso bloco nela passamos o id do nosso bloco ele precisa ser único para evitar conflitos dentro de nossa aplicação, título(title), ícone(icon), categoria(category), a função que será chamada no editor(edit) e a função que será salva no front-end de nossa aplicação(save).

Ativando nosso primeiro bloco Gutenberg

Com os nosso plugin/bloco Gutenberg pronto, chegou a hora de ativa-lo, primeiramente devemos armazenar os dois arquivos em uma pasta para fazer a instalação como plugin.

Adicionamos a pasta de nosso plugin em wp-content / plugins

No meu caso eu criei a pasta gutenberg-tutoriais mas pode ser qualquer nome para essa pasta. Após a adição da pasta em minha aplicação WordPress precisamos instalar o nosso plugin.

Se tudo ocorrer bem vamos visualizar nosso plugin em nosso dashboard. Agora vamos ativar e testar o nosso plugin

Como será exibido o nosso bloco

Nosso bloco ativado irá aparecer na categoria layout como definimos em nosso script e podemos ver as outras configurações como o título “primeiro bloco gutenberg”.

Quando adicionamos o bloco ele irá aparecer da seguinte forma:

Nosso bloco Gutenberg em nosso editor.

Salvando o nosso bloco o resultado será o seguinte:

Notem que as cores dos nossos blocos mudam de uma para outros isso foi adicionado de forma proposital. Podemos adicionar markups e estilos diferentes para o bloco que será exibido no editor e no front-end de nossa aplicação.

Fechamos por aqui nosso primeiro post, vamos evoluindo nossos exercícios a partir desse ponto. Para acompanhar os exercícios só seguir o repositório no github: https://github.com/fellyph/Gutenberg-tutorials

Categorias
Tutoriais Web

Ciclo de vida de um componente react

Ciclo de vida de um componente react, um recurso importante dentro do React onde temos maior controle sobre nossa aplicação. Imagine você quer criar um Timer que irá contar somente quando o componente estiver sendo exibido na tela. Qual seria o evento que poderíamos incluir caso o componente fosse removido da tela? 

React nos fornece uma série de funções dentro do nosso componente, para cada fase do seu ciclo de vida. Podemos acompanhar quando:

  • Montado – Mounting
  • Atualizado – Updating
  • Desmontado – Unmounting
  • Dispara um erro – Error Handling

Eventos de montagem

Temos o constructor e a função render executados quando nosso componente é criado mas temos uma função especifica para quando nosso componente é criado componentDidMount(), essa função será executada após o constructor and render serem executados. Elas possuem a seguinte ordem:

  • constructor()
  • static getDerivedStateFromProps()
  • render()
  • componentDidMount()

Eventos de atualização

Quando nosso componente é atualizando chamamos uma série de funções na seguinte ordem: 

  • static getDerivedStateFromProps()
  • shouldComponentUpdate()
  • render()
  • getSnapshotBeforeUpdate()
  • componentDidUpdate()

As funções marcadas como bold são as funções mais usadas, o resto são utilizadas em casos bem específicos

Eventos de desmontagem

Temos um evento específico para quando nosso componente é removido do nosso. 

  • componentWillUnmount()

Mas vocês podem se perguntar mas porque que chamar uma função pra quando o meu componente for removido da tela. Podemos ter alguns casos, temos um formulário e o usuário não enviou os dados queremos salvar essa info caso ele volte para esse componente ou simplesmente remover um listener ou um Timer, nesses casos temos o controle de executar qualquer ação antes desse componente seja removido do virtual DOM.

Eventos de erro

Se algum erro ocorrer durante a renderização, durante alguma função do ciclo de vida ou no construtor de qualquer componente. filho.

  • static getDerivedStateFromError() 
  • componentDidCatch()

Durante a evolução do React algumas funções ficaram para trás e foram descontinuadas, são elas:

  • componentWillMount()
  • componentWillUpdate()
  • componentWillReceiveProps()

Essas funções não são mais recomendadas pelo time do React, são classificadas como UNSAFE.

Exemplo 1

class CicloDeVida extends React.Component { constructor(props) { super(props); console.log('constructor'); } componentDidMount() { console.log('montou'); } render() { console.log('render'); return <h1>Ciclo de vida de um Component</h1>; } } ReactDOM.render( <CicloDeVida />, document.getElementById('root') );

No Exemplo 1, temos apenas a chamada do função componentDidMount() com o um console.log, para testarmos a ordem também adicionamos logs no construtor e no método render. E a saída será a seguinte:

Essa será a ordem de execução

Exemplo 2

class CicloDeVida extends React.Component { constructor(props) { super(props); console.log('constructor'); this.state = {timer: new Date()}; } updateTimer() { this.setState({ timer: new Date() }); } componentDidMount() { console.log('montou'); this.timerFunctionContainer = setInterval( () => this.updateTimer(), 1000 ); } componentDidUpdate() { console.log('atualizou'); } componentWillUnmount() { console.log('desmontou'); clearInterval(this.timerFunctionContainer); } render() { console.log('render'); return <React.Fragment> <h1>Ciclo de vida de um Component</h1> <p>Hora atual: {this.state.timer.toLocaleTimeString()}</p> </React.Fragment>; } } ReactDOM.render( <CicloDeVida />, document.getElementById('root') );

No exemplo 2, incluímos mais funcionalidades em nosso exemplo, agora temos um timer para exibir a hora atual. Adicionamos a propriedade timer em nosso estado. E na função componentDidmount irá incluir um setIterval para atualizar o timer a cada segundo, mas para garantir nenhum tipo de erro removemos o setInterval antes de desmontar o nosso componente. Outra observação sobre a ordem de chamada das funções:

Cada vez que o estado é atualizado chamamos, render e a função componentDidUpdate

Post anterior falei sobre eventos no react e qualquer dúvida deixe o comentário.

Categorias
Tutoriais Web

Eventos com React

Nesse post iremos ver como trabalhar eventos com react. Se você tem um background JavaScript. Quando trabalhamos com vanilla JavaScript temos várias formas de trabalhar com eventos, adicionando atributos no nosso elemento html, definindo o atributo no JavaScript ou adicionando um listener, direto no elemento HMTL seria da seguinte forma:

<button onclick="doSomething">Clique Aqui</button>

Este método trás muitos problemas, por exemplo, manutenção e gerenciamento de eventos. Outro formato adicionando um listener:

<script> document.getElementById('me').addEventListener('click', function(){ alert('hello') }); </script>

React tem seu próprio gerenciamento de evento por uma série de razoes, por exemplo, um diferente esquema de gerenciamento do DOM o virtualDOM, React tenta deixar o gerenciamento de eventos mais consistente. Todo evento retorna um SyntheticEvent, ele tem uma série de atributos:

boolean bubbles boolean cancelable DOMEventTarget currentTarget boolean defaultPrevented number eventPhase boolean isTrusted DOMEvent nativeEvent void preventDefault() boolean isDefaultPrevented() void stopPropagation() boolean isPropagationStopped() DOMEventTarget target number timeStamp string type

Outra questão importante eventos dentro de React sao passados como propriedade em camelCase onClick, ou onFocus, tambem podemos utilizar stopPropagation() ou preventDefault() como eventos nativos do JavaScript. O SyntheticEvent trabalha com o conceito de pooled, o objeto é limpo após o callback for invocado, por uma questão de performance.

  • Clipboard Events
  • Composition Events
  • Keyboard Events
  • Focus Events
  • Mouse Events
  • Selection Events
  • Touch Events
  • UI Events
  • Wheel Events
  • Media Events
  • Image Events
  • Animation Events
  • Transition Events

Antes de trabalhar com eventos precisamos entender é a questão de props e state, no exemplo abaixo quando publiquei este post(2 anos atrás) utilzei createClass formato utilizado com ES5 nessa versao vou utilizar ES6:

class ButtonComponent extends React.Component { constructor(props) { super(props); this.state = {active: true}; } toggle() { this.setState((prevStatus) => ({active: !prevStatus.active})); } render () { return <button onClick={() => this.toggle()}> Status:{this.state.active + ''} </button>; } } ReactDOM.render( <ButtonComponent />, document.getElementById('events') );

No exemplo acima crio um componente botão onde ele simplesmente faz o toggle de um atributo, poderia ser qualquer outro atributo ou interagir com outro elemento. O evento nos acionamos quando passamos o render do nosso componente neste caso onClick.

Lembrando todos os exemplos estão no meu github: https://github.com/fellyph/react-tutorial