Introdução

Forgo é uma biblioteca JavaScript leve (4 KB) para a criação de aplicativos da web. Embora seja cobrado como uma alternativa ao React e até mesmo use a sintaxe JSX, há várias diferenças importantes para se manter em mente ao trabalhar com o Forgo.

Neste artigo, veremos como criar aplicativos da web simples do lado do cliente com a biblioteca Forgo e, ao longo do caminho, veremos as diferenças entre Forgo e React.

Criando um componente simples com o Forgo

Para começar, devemos instalar o webpack e o webpack-cli globalmente executando:

 npm i-g webpack webpack-cli

Em seguida, clonamos o repositório JavaScript em nosso computador com o seguinte comando:

 npx degit jobsojs/forgo-template-javascript # main my-project

Depois de fazer isso, devemos pular para a pasta my-project e executar npm i para instalar os pacotes listados em package.json . npm start executará o projeto que acabamos de clonar.

Por padrão, o projeto é executado na porta 8080. Podemos alterar a porta na qual executamos o projeto adicionando a opção ---port=8888 , assim:

 npm start---port=8888 

O projeto que clonamos vem com um analisador JSX e outras ferramentas de construção, então não precisamos nos preocupar com as ferramentas do nosso projeto.

Agora podemos criar um componente simples escrevendo o seguinte em index.js :

 import {mount, rerender} de"forgo"; function Timer () { deixe segundos=0; Retorna { render (props, args) { setTimeout (()=> { segundos ++; rerender (args.element); }, 1000); retornar 
{segundos}
; }, }; }

Chamamos rerender com args.element para renderizar novamente um componente. Ao contrário do React, os estados são armazenados em variáveis ​​regulares em vez de estados, e renderizamos os segundos na instrução return .

Montagem do componente

Para montar o componente, adicionaríamos:

 window.addEventListener ("load", ()=> { montagem (, document.getElementById ("root"));
});

Portanto, junto com o componente de amostra que acabamos de escrever em index.js , temos:

 import {mount, rerender} de"forgo"; function Timer () { deixe segundos=0; Retorna { render (props, args) { setTimeout (()=> { segundos ++; rerender (args.element); }, 1000); retornar 
{segundos}
; }, }; } window.addEventListener ("load", ()=> { montagem (, document.getElementById ("root")); });

Podemos substituir document.getElementById pelo seletor de elemento, para que possamos escrever:

 window.addEventListener ("load", ()=> { montagem (,"#root");
});

Componentes filhos e adereços

Assim como no React, podemos criar componentes filhos e passá-los adereços. Para fazer isso, escrevemos:

 import {mount} de"forgo"; function Parent () { Retorna { render () { Retorna ( 
); }, }; } function Greeter ({name}) { Retorna { render (props, args) { return
hi {name}
; }, }; } window.addEventListener ("load", ()=> { mount (, document.getElementById ("root")); });

O componente Greeter é filho do componente Parent . Greeter aceita a prop name , que adicionamos na instrução return para renderizar seu valor.

Também podemos adicionar entradas facilmente com o Forgo. Para fazer isso, escreveríamos:

 import {mount} de"forgo"; function Input () { const inputRef={}; Retorna { render () { function onClick () { const inputElement=inputRef.value; alert (inputElement.value); } Retorna ( 
); }, }; } window.addEventListener ("load", ()=> { montagem (, document.getElementById ("root")); });

Criamos uma variável de objeto chamada inputRef e a passamos para o prop ref do elemento de entrada. Em seguida, obtemos o objeto do elemento de entrada com a propriedade inputRef.value , como fizemos no método onClick . Agora podemos obter a propriedade value para obter o valor de entrada.

Listas e chaves

Semelhante ao React, podemos renderizar listas chamando map em um array e, em seguida, retornando os componentes que queremos renderizar. Por exemplo, podemos escrever:

 import {mount} de"forgo"; function App () { Retorna { render () { const pessoas=[ {nome:"james", id: 1}, {nome:"maria", id: 2}, ]; Retorna ( 
{people.map (({key, name})=> ( ); }, }; } function Child () { Retorna { render ({name}) { return
hi {name}
; }, }; } window.addEventListener ("load", ()=> { mount (, document.getElementById ("root")); });

Temos um componente App com uma matriz people . Podemos renderizar a matriz no navegador chamando map e, em seguida, retornando o componente Child com a chave e o nome adereços.

A propriedade key permite que Forgo distinga entre os itens renderizados atribuindo a eles um ID único. name é um prop regular que obtemos no componente Child e renderizamos.

Buscando dados

Podemos buscar dados com promessas, assim como fazemos com os componentes React. No entanto, só podemos usar o método then para obter dados; não assíncrono/espera. Se usarmos async e await , obteremos um erro regeneratorRuntime not defined .

Assim, para obter dados quando um componente é montado, podemos escrever algo assim:

 import {mount, rerender} de"forgo"; function App () { deixe dados; Retorna { render (_, args) { if (! dados) { fetch ('https://yesno.wtf/api') .então (res=> res.json ()) .então (d=> { dados=d; rerender (args.element); }) retornar 

carregando

} retornar
{JSON.stringify (data)}
}, }; } window.addEventListener ("load", ()=> { montagem (, document.getElementById ("root")); });

data inicialmente não tem valor, nesse caso chamamos fetch para fazer uma solicitação GET para alguns dados. Em seguida, atribuímos o parâmetro d a data , que contém os dados de resposta.

Chamamos rerender com args.element para renderizar novamente o componente após a atualização de dados e, no próximo ciclo de renderização, o o valor data stringificado é renderizado. Agora devemos ser capazes de ver os dados que recuperamos da API.

Eventos e erros

Um componente Forgo emite vários eventos ao longo de seu ciclo de vida de renderização. Vamos pegar o seguinte componente como exemplo:

 import {mount} de"forgo"; function App () { Retorna { render (props, args) { return 
Olá
; }, montagem (adereços, args) { console.log (`montado no nó com id $ {args.element.node.id}`); }, desmontar (props, args) { console.log ("desmontado"); }, }; } window.addEventListener ("load", ()=> { mount (, document.getElementById ("root")); });

Nosso método render retorna um div com o ID hello e, quando um componente é montado, chamamos o método mount . args.element.node.id obtém o valor do atributo id do elemento raiz, portanto, seu valor deve ser 'hello'.

Portanto, devemos ver 'montado no nó com id hello' registrado. O método unmount é executado quando o componente é desmontado, portanto, devemos ver 'unmounted' quando o componente é removido do DOM.

Por exemplo, digamos que temos:

 import {mount, rerender} de"forgo"; function App () { deixe showChild=false Retorna { render (props, args) { const onClick=()=> { showChild=! showChild rerender (args.element) } Retorna ( 
{showChild? : indefinido}
); }, }; } function Child () { Retorna { render (props, args) { retornar
filho
; }, desmontar (props, args) { console.log ("desmontado"); }, }; } window.addEventListener ("load", ()=> { mount (, document.getElementById ("root")); });

Quando clicamos no botão alternar , o componente Filho desaparecerá e devemos ver 'desmontado'.

Também podemos escolher quando renderizar novamente um componente chamando rerender manualmente com a função shouldUpdate . shouldUpdate tem os parâmetros newProps e oldProps , que, como seus nomes indicam, fornecem os valores atuais e antigos dos props, respectivamente.

Considere o seguinte exemplo:

 import {mount, rerender} de"forgo"; function App () { deixe nome='james' Retorna { render (props, args) { const onClick=()=> { nome=nome==='james'?'jane':'james' rerender (args.element) } Retorna ( 
); }, }; } function Greeter () { Retorna { render ({name}, args) { return
hi {name}
; }, shouldUpdate (newProps, oldProps) { console.log (newProps, oldProps) return newProps.name!==oldProps.name; }, }; } window.addEventListener ("load", ()=> { montagem (, document.getElementById ("root")); });

O botão alternar alterna o valor de nome , que passamos como o valor de Greeter nome prop. Portanto, sempre que clicarmos no botão alternar , veremos a atualização do registro do console.

Finalmente, podemos lidar com erros no objeto que retornamos com o método error . Erros de componentes filhos são transmitidos ao pai.

Então, se tivermos:

 import {mount} de"forgo"; function App () { Retorna { render () { Retorna ( 
); }, erro (props, args) { Retorna ( p {args.error.message}

); }, }; } function BadComponent () { Retorna { render () { lance novo erro ("erro"); }, }; } window.addEventListener ("load", ()=> { montagem (, document.getElementById ("root")); });

args.error.message deve ter a string que passamos para o construtor Error , pois o erro se propaga do componente filho para o pai.

Conclusão

Com apenas 4KB, o Forgo é uma pequena alternativa ao React que nos permite criar componentes simples com facilidade. Uma vez que usa sintaxe JSX, deve parecer familiar para os desenvolvedores do React.

No entanto, existem algumas diferenças importantes de comportamento. A nova renderização deve ser feita manualmente com o método rerender . Os ciclos de vida dos componentes também são bastante diferentes e os estados são armazenados como variáveis ​​simples em vez de estados. Também não há ganchos; em vez disso, usamos métodos de ciclo de vida para realizar várias ações durante o ciclo de vida de um componente.

A maneira mais fácil de começar a usar o Forgo é instalar as dependências do webpack dev globalmente e, em seguida, clonar o projeto inicial com degit .

A postagem Introdução ao Forgo.JS, uma IU ultraleve runtime apareceu primeiro no LogRocket Blog .

Source link