portaldacalheta.pt
  • Principal
  • Web Front-End
  • Gestão De Engenharia
  • Ciência De Dados E Bancos De Dados
  • Ascensão Do Remoto
Web Front-End

Navegando no Ecossistema React.JS



navegando no ecossistema react.js

A velocidade da inovação no JavaScript Land é tão alta que algumas pessoas até pensam que é contraproducente . Uma biblioteca pode ir de um brinquedo de adoção inicial, ao estado da arte, à obsolescência no curso de alguns meses. Ser capaz de identificar uma ferramenta que vai permanecer relevante por pelo menos mais um ano está se tornando uma arte.



Quando React.js era liberado dois anos atrás, eu estava aprendendo Angular, e rapidamente descartei o React como uma biblioteca obscura de outro modelo. Durante esses dois anos, a Angular realmente ganhou uma posição segura entre Desenvolvedores de JavaScript , e quase se tornou sinônimo de desenvolvimento JS moderno. Até comecei a ver o Angular em ambientes corporativos muito conservadores e achei que era um futuro brilhante como garantido.



Mas de repente, uma coisa estranha aconteceu. Parece angular tornou-se uma vítima do efeito Osborne , ou “morte por pré-anúncio”. A equipe anunciou que, em primeiro lugar, o Angular 2 será completamente diferente, sem um caminho de migração claro do Angular 1, e, em segundo lugar, que o Angular 2 não estará disponível por mais um ano ou mais. O que isso diz a alguém que deseja iniciar um novo projeto da web? Você deseja escrever seu novo projeto em uma estrutura que se tornará obsoleta com o lançamento de uma nova versão?



Essa ansiedade entre os desenvolvedores jogou a favor do React, que buscava se estabelecer na comunidade. Mas React sempre se comercializou como o “V” em “MVC”. Isso causou certa frustração entre os desenvolvedores da web, que estão acostumados a trabalhar com estruturas completas. Como faço para preencher as peças que faltam? Devo escrever o meu próprio? Devo apenas usar uma biblioteca existente? Se sim, qual?

Com certeza, o Facebook (criadores do React.js) tinha mais um ás na manga: o Fluxo fluxo de trabalho, que prometia preencher as funções 'M' e 'C' ausentes. Para tornar as coisas ainda mais interessantes, o Facebook afirmou que o Flux é um “padrão”, não um framework, e sua implementação do Flux é apenas um exemplo do padrão. Fiel à sua palavra, sua implementação foi realmente simplista e envolveu a escrita de muitos prolixo , boilerplate repetitivo para fazer as coisas andarem.



A comunidade de código aberto veio em nosso socorro e, um ano depois, temos dezenas de bibliotecas Flux e até mesmo alguns meta-projetos voltados para comparando-os . Isto é uma coisa boa; em vez de lançar alguma estrutura corporativa pronta, o Facebook conseguiu despertar o interesse da comunidade e encorajou as pessoas a apresentarem suas próprias soluções.

Há um efeito colateral interessante nessa abordagem: quando você precisa combinar muitas bibliotecas diferentes para obter seu framework completo, você está escapando efetivamente do aprisionamento do fornecedor e as inovações que surgem durante a construção de seu próprio framework podem ser prontamente reutilizadas em outro lugar.



É por isso que as novidades Reagir é tão interessante; a maior parte pode ser prontamente reutilizada em outros ambientes JavaScript. Mesmo que você não planeje usar o React, dar uma olhada em seu ecossistema é inspirador. Você pode querer simplificar seu sistema de compilação usando o poderoso, mas comparativamente fácil de configurar, empacotador de módulo Webpack , ou comece a escrever ECMAScript 6 e até ECMAScript 7 hoje com o Babel compilador.

Neste artigo, examinarei alguns dos recursos e bibliotecas interessantes que estão disponíveis. Então, vamos explorar o ecossistema React!



React Explorer Man

Sistema de construção

O sistema de construção é indiscutivelmente a primeira coisa com a qual você deve se preocupar ao criar um novo aplicativo da web. O sistema de construção não é apenas uma ferramenta para a execução de scripts, mas, no mundo do JavaScript, geralmente molda a estrutura geral do seu aplicativo. As tarefas mais importantes que um sistema de compilação deve cobrir são as seguintes:



  • Gerenciando dependências externas e internas
  • Executando compiladores e pré-processadores
  • Otimizando ativos para produção
  • Executar o servidor da web de desenvolvimento, observador de arquivos e recarregador de navegador

Nos últimos anos, o Yeoman fluxo de trabalho com Bower e Terra foram apresentados como o Santíssima Trindade de desenvolvimento de front-end moderno, resolvendo os problemas de geração padrão, gerenciamento de pacotes e tarefas comuns em execução, respectivamente, com o folk mais progressivo mudando de Grunt para Gole recentemente.

No ambiente React, você pode esquecê-los com segurança. Não que você não possa usá-los, mas é provável que você simplesmente consiga usar Webpack e bom velho NPM . Como isso é possível? Webpack é um empacotador de módulo, que implementa CommonJS módulo sintaxe, comum no mundo Node.js, no navegador também. Na verdade, torna as coisas mais simples, pois você não precisa aprender outro gerenciador de pacotes para front end; você apenas usa o NPM e compartilha dependências entre o servidor e o front end. Você também não precisa lidar com o problema de carregar os arquivos JS na ordem correta, porque isso é inferido das importações de dependência especificadas em cada arquivo, e todo o enxame está corretamente concatenado em um script carregável.



Webpack Logo Webpack

Para tornar as coisas ainda mais atraentes, Webpack, ao contrário de seu primo mais velho Browserify , também pode lidar com outros tipos de ativos. Por exemplo, com carregadores , você pode transformar qualquer arquivo de ativo em uma função JavaScript que inline ou carrega o arquivo referenciado. Portanto, esqueça o pré-processamento manual e a referência de ativos do HTML. Apenas require seus arquivos CSS / SASS / LESS do JavaScript, e o Webpack cuida do resto com um simples arquivo de configuração . Webpack também inclui um servidor da web de desenvolvimento e um observador de arquivos. Além disso, você pode usar o 'scripts' digite package.json para definir linhas de shell:

{ 'name': 'react-example-filmdb', 'version': '0.0.1', 'description': 'Isomorphic React + Flux film database example', 'main': 'server/index.js', 'scripts': { 'build': './node_modules/.bin/webpack --progress --stats --config ./webpack/prod.config.js', 'dev': 'node --harmony ./webpack/dev-server.js', 'prod': 'NODE_ENV=production node server/index.js', 'test': './node_modules/.bin/karma start --single-run', 'postinstall': 'npm run build' } ... }

E isso é tudo que você precisa para substituir Gulp e Bower. Claro, você ainda pode usar o Yeoman para gerar clichês de aplicativos. Não desanime quando não há gerador Yeoman para o que você deseja (as bibliotecas mais modernas geralmente não têm um). Você ainda pode simplesmente clonar alguns clichês do GitHub e hackear.

Relacionado: Como os componentes do React facilitam o teste de interface do usuário

ECMAScript de amanhã, hoje

O ritmo de desenvolvimento da linguagem JavaScript aumentou substancialmente nos últimos anos e, após um período de remoção de peculiaridades e estabilização da linguagem, agora vemos novos recursos poderosos chegando. O esboço de especificação ECMAScript 6 (ES6) foi finalizado e, embora ainda não tenha sido oficializado, já está tendo ampla adoção. O trabalho no ECMAScript 7 (ES7) está em andamento, mas muitos de seus recursos já estão sendo adotados pelas bibliotecas mais modernas.

Logotipo ECMAScript 7 ECMAScript 7

Como isso é possível? Talvez você pense que não pode tirar proveito desses novos recursos JavaScript brilhantes até que eles sejam suportados no Internet Explorer, mas pense novamente. Os transpiladores ES já se tornaram tão onipresentes que podemos até mesmo passar sem o suporte de navegador adequado. O melhor transpiler ES disponível agora é Babel : ele pegará seu código ES6 + mais novo e o transformará em vanilla ES5, então, você pode usar qualquer novo recurso do ES assim que for inventado (e implementado no Babel, o que geralmente acontece muito rapidamente).

Logotipo da Babel Babel

Os mais novos recursos de JavaScript são úteis em todas as estruturas de front-end e o React foi atualizado recentemente para funcionar bem com as especificações ES6 e ES7. Esses novos recursos devem eliminar muitas dores de cabeça ao desenvolver com o React. Vamos dar uma olhada em algumas das adições mais úteis e como elas podem beneficiar um projeto React. Posteriormente, veremos como usar algumas ferramentas e bibliotecas úteis com o React enquanto aproveitamos essa sintaxe aprimorada.

Aulas ES6

A programação orientada a objetos é um paradigma poderoso e amplamente adotado, mas a abordagem do JavaScript é um pouco exótica. A maioria dos frameworks de front-end, sejam Backbone, Ember, Angular ou React, adotaram assim suas próprias maneiras proprietárias de definir classes e criar objetos. Mas com o ES6, agora temos classes tradicionais em JavaScript e simplesmente faz sentido usá-las em vez de escrever nossa própria implementação. Então, em vez de:

React.createClass({ displayName: 'HelloMessage', render() { return Hello {this.props.name} ; } })

nós podemos escrever:

class HelloMessage extends React.Component { render() { return Hello {this.props.name} ; } }

Para um exemplo mais elaborado, considere este código, usando a sintaxe antiga:

React.createClass({ displayName: 'Counter', getDefaultProps: function(){ return {initialCount: 0}; }, getInitialState: function() { return {count: this.props.initialCount} }, propTypes: {initialCount: React.PropTypes.number}, tick() { this.setState({count: this.state.count + 1}); }, render() { return ( Clicks: {this.state.count} ); } });

E compare com a versão ES6:

class Counter extends React.Component { static propTypes = {initialCount: React.PropTypes.number}; static defaultProps = {initialCount: 0}; constructor(props) { super(props); this.state = {count: props.initialCount}; } state = {count: this.props.initialCount}; tick() { this.setState({count: this.state.count + 1}); } render() { return ( Clicks: {this.state.count} ); } }

Aqui, os métodos de ciclo de vida React getDefaultProps e getInitialState não são mais necessários. getDefaultProps torna-se a variável de classe estática defaultProps, e o estado inicial é apenas definido no construtor. A única desvantagem é que os métodos não são mais autobound, então você deve usar bind ao chamar manipuladores de JSX .

Decoradores

Decoradores são um recurso útil do ES7. Eles permitem que você aumente o comportamento de uma função ou classe envolvendo-a dentro de outra função. Por exemplo, vamos supor que você deseja ter o mesmo manipulador de alterações em alguns de seus componentes, mas não quer se comprometer com o antipadrão de herança . Você pode usar um decorador de classe. Vamos definir o decorador da seguinte maneira:

addChangeHandler: function(target) { target.prototype.changeHandler = function(key, attr, event) { var state = {}; state[key] = this.state[key] || {}; state[key][attr] = event.currentTarget.value; this.setState(state); }; return target; }

O importante aqui é que a função addChangeHandler adiciona o changeHandler função para o protótipo da classe de destino.

Para aplicar o decorador, poderíamos escrever:

MyClass = changeHandler(MyClass)

ou mais elegante, com sintaxe ES7:

@addChangeHandler class MyClass { ... }

Quanto ao conteúdo do changeHandler função em si, com a ausência do React de vinculação de dados bidirecional, trabalhar com entradas no React pode ser entediante. O changeHandler função tenta torná-lo mais fácil. O primeiro parâmetro especifica um key no objeto de estado, que servirá como um objeto de dados para a entrada. O segundo parâmetro é o atributo, no qual o valor do campo de entrada será salvo. Esses dois parâmetros são definidos no JSX usando o bind palavra-chave.

@addChangeHandler class LoginInput extends React.Component { constructor(props) { super(props); this.state = { login: {} }; } render() { return ( ) } }

Quando o usuário altera o campo de nome de usuário, seu valor é salvo em this.state.login.username, sem a necessidade de definir mais manipuladores personalizados.

Funções de seta

Dinâmica do JavaScript this contexto tem sido uma dor constante para os desenvolvedores porque, de forma um tanto não intuitiva, o this o contexto de uma função aninhada é redefinido como global, mesmo dentro de uma classe. Para corrigir isso, geralmente é necessário salvar this para alguma variável de escopo externo (geralmente _this) e use-a em funções internas:

class DirectorsStore { onFetch(directors) { var _this = this; this.directorsHash = {}; directors.forEach(function(x){ _this.directorsHash[x._id] = x; }) } }

Com a nova sintaxe ES6, o function(x){ pode ser reescrito como (x) => {. Esta definição de método de “seta” não apenas vincula corretamente this para o escopo externo, mas também é consideravelmente mais curto, o que definitivamente conta ao escrever muito código assíncrono.

onFetch(directors) { this.directorsHash = {}; directors.forEach((x) => { this.directorsHash[x._id] = x; }) }

Atribuições de Destruição

Atribuições de desestruturação, introduzidas no ES6, permitem que você tenha um objeto composto no lado esquerdo de uma atribuição:

var o = {p: 42, q: true}; var {p, q} = o; console.log(p); // 42 console.log(q); // true

Isso é bom, mas como isso realmente nos ajuda no React? Considere o seguinte exemplo:

se eles rodarem eles vc
function makeRequest(url, method, params) { var config = { url: url, method: method, params: params }; ... }

Com a desestruturação, você pode economizar algumas teclas. As teclas literais {url, method, params} são atribuídos automaticamente a valores do escopo com os mesmos nomes das chaves. Esse idioma é usado com bastante frequência e a eliminação da repetição torna o código menos sujeito a erros.

function makeRequest(url, method, params) { var config = {url, method, params}; ... }

A desestruturação também pode ajudá-lo a carregar apenas um subconjunto de um módulo:

const {clone, assign} = require('lodash'); function output(data, optional) { var payload = clone(data); assign(payload, optional); }

Argumentos: Default, Rest e Spread

Os argumentos da função são mais poderosos no ES6. Finalmente, você pode definir o padrão argumento:

function http(endpoint, method='GET') { console.log(method) ... } http('/api') // GET

Cansado de mexer com pessoas pesadas arguments objeto? Com a nova especificação, você pode obter o descansar dos argumentos como uma matriz:

function networkAction(context, method, ...rest) { // rest is an array return method.apply(context, rest); }

E se você não gosta de ligar para apply(), você pode apenas espalhar uma matriz em argumentos de função:

myArguments = ['foo', 'bar', 123]; myFunction(...myArguments);

Geradores e funções assíncronas

ES6 introduziu geradores de JavaScript. Um gerador é basicamente uma função JavaScript cuja execução pode ser pausada e reiniciada posteriormente, lembrando seu estado. Cada vez que yield a palavra-chave é encontrada, a execução é pausada e yield argumento é passado de volta para o objeto de chamada:

function* sequence(from, to) { console.log('Ready!'); while(from <= to) { yield from++; } }

Aqui está um exemplo deste gerador em ação:

> var cursor = sequence(1,3) Ready! > cursor.next() { value: 1, done: false } > cursor.next() { value: 2, done: false } > cursor.next() { value: 3, done: false } > cursor.next() { value: undefined, done: true }

Quando chamamos a função geradora, ela é executada até o primeiro yield e então para. Depois de chamarmos next(), ele retorna o primeiro valor e retoma a execução. Cada yield retorna outro valor, mas após a terceira chamada, a função geradora termina e cada chamada subsequente para next() retornará { value: undefined, done: true }.

Claro, o objetivo dos geradores não é criar sequências numéricas elaboradas. A parte interessante é a capacidade de interromper e retomar a execução da função, que pode ser usada para controlar o fluxo do programa assíncrono e, finalmente, se livrar dessas funções de retorno de chamada incômodas.

Para demonstrar essa ideia, primeiro precisamos de uma função assíncrona. Normalmente, teríamos alguma operação de E / S, mas para simplificar, vamos apenas usar setTimeout e devolver um promessa . (Observe que ES6 também introduziu promessas nativas para JavaScript.)

function asyncDouble(x) { var deferred = Promise.defer(); setTimeout(function(){ deferred.resolve(x*2); }, 1000); return deferred.promise; }

Em seguida, precisamos de uma função de consumidor:

function consumer(generator){ var cursor = generator(); var value; function loop() { var data = cursor.next(value); if (data.done) { return; } else { data.value.then(x => { value = x; loop(); }) } } loop(); }

Esta função recebe qualquer gerador como argumento e continua chamando next() nele, desde que existam valores para yield. Neste caso, os valores gerados são promessas, portanto, é necessário aguardar a resolução das promessas e usar a recursão com loop() para realizar o loop em funções aninhadas.

O valor de retorno é resolvido no then() manipulador e passado para value, que é definido no escopo externo e que será passado para next(value) ligar. Essa chamada torna o valor um resultado da expressão de rendimento correspondente. Isso significa que agora podemos escrever de forma assíncrona, sem nenhum retorno de chamada:

function* myGenerator(){ const data1 = yield asyncDouble(1); console.log(`Double 1 = ${data1}`); const data2 = yield asyncDouble(2); console.log(`Double 2 = ${data2}`); const data3 = yield asyncDouble(3); console.log(`Double 3 = ${data3}`); } consumer(myGenerator);

O gerador myGenerator será pausado em cada yield, esperando que o consumidor cumpra a promessa resolvida. E, de fato, veremos os números calculados aparecerem no console em intervalos de um segundo.

Double 1 = 2 Double 2 = 4 Double 3 = 6

Isso demonstra o conceito básico, no entanto, não recomendo que você use este código na produção. Em vez disso, escolha uma biblioteca bem testada, como o que . Isso permitirá que você escreva facilmente código assíncrono com rendimentos, incluindo tratamento de erros:

co(function *(){ var a = yield Promise.resolve(1); console.log(a); var b = yield Promise.resolve(2); console.log(b); var c = yield Promise.resolve(3); console.log(c); }).catch(function(err){ console.error(err.stack); });

Portanto, este exemplo mostra como escrever código assíncrono sem retornos de chamada usando geradores ES6. ES7 leva esta abordagem um passo adiante, introduzindo o async e await palavras-chave e eliminando a necessidade de uma biblioteca de gerador. Com esse recurso, o exemplo anterior ficaria assim:

async function (){ try { var a = await Promise.resolve(1); console.log(a); var b = await Promise.resolve(2); console.log(b); var c = await Promise.resolve(3); console.log(c); } catch (err) { console.error(err.stack); } };

Em minha opinião, isso facilita o trabalho com código assíncrono em JavaScript. Não apenas no React, mas em todos os outros lugares também.

Os geradores não são apenas mais concisos e diretos, mas também nos permitem usar técnicas que seriam muito difíceis de implementar com callbacks. Um exemplo proeminente da bondade do gerador é o Além disso Biblioteca de middleware para Node.js. Ele visa substituir o Express e, para esse objetivo, vem com um recurso matador: a cadeia de middleware flui não apenas Rio abaixo (com solicitação do cliente), mas também rio acima , permitindo modificações adicionais na resposta do servidor. Considere o seguinte exemplo de servidor koa:

// Response time logger middleware app.use(function *(next){ // Downstream var start = new Date; yield next; // Upstream this.body += ' World'; var ms = new Date - start; console.log('%s %s - %s', this.method, this.url, ms); }); // Response handler app.use(function *(){ this.body = 'Hello'; }); app.listen(3000);

Por favor logo Por favor

O middleware de resposta yield s downstream no manipulador de resposta, que define o corpo da resposta, e no fluxo upstream (após a expressão yield), modificação adicional de this.body é permitido, bem como outras funções, como registro de tempo, o que é possível porque o upstream e o downstream compartilham o mesmo contexto de função. Isso é muito mais poderoso do que Expressar , em que uma tentativa de realizar a mesma coisa terminaria assim:

var start; // Downstream middleware app.use(function(req, res, next) { start = new Date; next(); // Already returned, cannot continue here }); // Response app.use(function (req, res, next){ res.send('Hello World') next(); }); // Upstream middleware app.use(function(req, res, next) { // res already sent, cannot modify var ms = new Date - start; console.log('%s %s - %s', this.method, this.url, ms); next(); }); app.listen(3000);

Você provavelmente já pode identificar o que está errado aqui; usando um “global” start variável resultará em uma condição de corrida, retornando sem sentido com solicitações simultâneas. A solução é uma solução alternativa não óbvia e você pode esquecer de modificar a resposta no fluxo upstream.

Além disso, ao usar o koa, você obterá o fluxo de trabalho assíncrono do gerador gratuitamente:

app.use(function *(){ try { const part1 = yield fs.readFile(this.request.query.file1, 'utf8'); const part2 = yield fs.readFile(this.request.query.file2, 'utf8'); this.body = part1 + part2; } catch (err) { this.status = 404 this.body = err; } }); app.listen(3000);

Você pode imaginar as promessas e retornos de chamada envolvidos na recriação deste pequeno exemplo no Express.

Logotipo Node.js

levantando um fundo de private equity

Como toda essa conversa sobre Node.js se relaciona com o React? Bem, o Node é a primeira escolha ao considerar um back-end adequado para o React. Como o Node também é escrito em JavaScript, ele oferece suporte ao compartilhamento de código entre o back-end e o front-end, permitindo-nos construir isomórfico Reaja aplicações web. Mas, mais sobre isso mais tarde.

Biblioteca Flux

O React é excelente na criação de componentes de visualização combináveis, mas precisamos de alguma forma de gerenciar os dados e o estado em todo o aplicativo. É quase universalmente aceito que o React é melhor complementado pela arquitetura do aplicativo Flux. Se você é completamente novo no Flux, eu recomendo um rápido refrescar .

Flux Logo Fluxo

O que não foi universalmente aceito é qual das muitas implementações do Flux escolher. Facebook Fluxo seria a escolha óbvia, mas para a maioria das pessoas é muito prolixo. Implementações alternativas se concentram principalmente na redução da quantidade de clichê necessária com uma abordagem de convenção sobre configuração e também com algumas funções de conveniência para componentes de ordem superior, renderização do lado do servidor e assim por diante. Alguns dos principais candidatos, com várias métricas de popularidade, podem ser vistos Aqui . Eu pesquisei Alt, Reflux, Flummox, Fluxxor e Marty.js.

Minha maneira de escolher a biblioteca certa não é objetiva, mas pode ajudar de qualquer maneira. Fluxxor foi uma das primeiras bibliotecas que verifiquei, mas agora parece um pouco desatualizada. Marty.js é interessante e tem muitos recursos, mas ainda envolve muitos clichês e algumas das funções parecem supérfluas. Refluxo parece ótimo e tem alguma tração, mas parece um pouco difícil para iniciantes e também carece da documentação adequada. Flummox e Tudo são muito semelhantes, mas Alt parece ter ainda menos clichê, desenvolvimento muito ativo, atualizado documentação e um útil Folga comunidade. Portanto, escolhi Alt.

Alt Flux

Logotipo Alt Flux Alt Flux

Com Alt, o fluxo de trabalho do Flux se torna muito mais simples sem perder nada de seu poder. Fluxo do Facebook documentação diz muito sobre o despachante, mas somos livres para ignorar isso porque, em Tudo , o despachante está implicitamente conectado às ações por convenção e geralmente não requer nenhum código personalizado. Isso nos deixa apenas lojas , ações , e componentes . Essas três camadas podem ser usadas de forma que sejam bem mapeadas no MVC modelo de pensamento: as lojas são Modelos , ações são Controladores , e os componentes são Visualizações . A principal diferença é o fluxo de dados unidirecional central para o padrão Flux, o que significa que os controladores (ações) não podem modificar diretamente as visualizações (componentes), mas, em vez disso, podem apenas acionar modificações do modelo (armazenar), às quais as visualizações são passivamente vinculadas. Isso já era uma prática recomendada para alguns iluminado Desenvolvedores angulares.

Fluxos de trabalho x Alt

O fluxo de trabalho é o seguinte:

  1. Os componentes iniciam ações.
  2. As lojas ouvem as ações e atualizam os dados.
  3. Os componentes são vinculados a armazenamentos e renderizados novamente quando os dados são atualizados.

Ações

Ao usar a biblioteca Alt Flux, as ações geralmente vêm em dois sabores: automático e manual. Ações automáticas são criadas usando generateActions função, e eles vão diretamente para o despachante. Os métodos manuais são definidos como métodos de suas classes de ação e podem ir para o despachante com uma carga adicional. O caso de uso mais comum de ações automáticas é notificar as lojas sobre algum evento no aplicativo. Ações manuais são, entre outras coisas, o preferido maneira de lidar com as interações do servidor.

Portanto, as chamadas da API REST pertencem às ações. O fluxo de trabalho completo é o seguinte:

  1. O componente aciona uma ação.
  2. O criador da ação executa uma solicitação assíncrona do servidor e o resultado vai para o despachante como uma carga útil.
  3. A loja escuta a ação, o manipulador de ação correspondente recebe o resultado como um argumento e a loja atualiza seu estado de acordo.

Para solicitações AJAX, podemos usar o axios biblioteca, que, entre outras coisas, lida com dados JSON e cabeçalhos perfeitamente. Em vez de promessas ou retornos de chamada, podemos usar o ES7 async / await padronizar. Se o POST o status da resposta não é 2XX, um erro é gerado e despachamos os dados retornados ou o erro recebido.

Vejamos uma página de login para um exemplo simples do fluxo de trabalho Alt. A ação de logout não precisa fazer nada de especial, apenas avisar a loja, para que possamos gerá-la automaticamente. A ação de login é manual e espera os dados de login como um parâmetro para o criador da ação. Depois de obter uma resposta do servidor, despachamos os dados de sucesso ou, se ocorrer um erro, despachamos o erro recebido.

class LoginActions { constructor() { // Automatic action this.generateActions('logout'); } // Manual action async login(data) { try { const response = await axios.post('/auth/login', data); this.dispatch({ok: true, user: response.data}); } catch (err) { console.error(err); this.dispatch({ok: false, error: err.data}); } } } module.exports = (alt.createActions(LoginActions));

Lojas

O armazenamento do Flux tem dois propósitos: tem manipuladores de ação e carrega o estado. Vamos continuar nosso exemplo de página de login para ver como isso funciona.

Vamos criar LoginStore, com dois atributos de estado: user, para o usuário conectado no momento, e error, para o erro relacionado ao login atual. No espírito de reduzir o clichê, Alt nos permite vincular a todas as ações de uma classe com uma única função bindActions.

class LoginStore { constructor() { this.bindActions(LoginActions); this.user = null; this.error = null; } ...

Os nomes dos manipuladores são definidos por convenção, precedendo on ao nome da ação correspondente. Portanto, o login a ação é controlada por onLogin e assim por diante. Observe que a primeira letra do nome da ação será maiúscula no estilo camelCase. Em nosso LoginStore, temos os seguintes manipuladores, chamados pelas ações correspondentes:

... onLogin(data) { if (data.ok) { this.user = data.user; this.error = null; router.transitionTo('home'); } else { this.user = null; this.error = data.error } } onLogout() { this.user = null; this.error = null; } }

Componentes

A maneira usual de vincular armazenamentos a componentes é usar algum tipo de mixin React. Mas como os mixins estão indo fora de moda , deve haver alguma outra maneira. Uma das novas abordagens é usar componentes de ordem superior. Pegamos nosso componente e o colocamos dentro de um componente wrapper, que se encarregará de ouvir os armazenamentos e chamar a re-renderização. Nosso componente receberá o estado da loja em props. Essa abordagem também é útil para organizar nosso código em inteligente e burro componentes, que estão na moda ultimamente. Para Alt, o wrapper do componente é implementado por AltContainer:

export default class Login extends React.Component { render() { return ( )} }

Nosso LoginPage componente também usa o changeHandler decorador introduzido anteriormente. Dados de LoginStore é usado para exibir erros no caso de um login malsucedido e a re-renderização é realizada por AltContainer. Clicar no botão de login executa o login ação, completando o fluxo de trabalho Alt flux:

@changeHandler export default class LoginPage extends React.Component { constructor(props) { super(props); this.state = { loginForm: {} }; } login() { LoginActions.login(this.state.loginForm) } render() { return ( {{this.props.LoginStore.error}} Login )} }

Renderização Isomórfica

Os aplicativos da web isomórficos são um assunto em alta atualmente porque resolvem algumas das maiores tarefas dos aplicativos tradicionais de página única. Nesses aplicativos, a marcação é criada dinamicamente por JavaScript no navegador. O resultado é que o conteúdo não está disponível para clientes com JavaScript desativado, principalmente os rastreadores da web de mecanismos de pesquisa. Isso significa que sua página da web não está indexada e não aparece nos resultados da pesquisa. Existem maneiras de contornar isso , mas estão longe de ser ideais. A abordagem isomórfica tenta corrigir esse problema pré-renderizando a URL solicitada de um aplicativo de página única no servidor. Com o Node.js, você tem JavaScript no servidor, o que significa que o React também pode ser executado no lado do servidor. Isso não deve ser muito difícil, certo?

Um obstáculo é que algumas bibliotecas do Flux, especialmente aquelas que usam singletons, têm dificuldades com a renderização do lado do servidor. Quando você tem armazenamentos de Flux singleton e várias solicitações simultâneas para seu servidor, os dados se misturam. Algumas bibliotecas resolvem isso usando instâncias do Flux, mas isso vem com outras desvantagens, particularmente a necessidade de passar essas instâncias em seu código. Alt oferece instâncias do Flux também, mas também resolveu o problema de renderização do lado do servidor com singletons; ele libera os armazenamentos após cada solicitação, de modo que cada solicitação simultânea comece do zero.

O núcleo da funcionalidade de renderização do lado do servidor é fornecido por React.renderToString. Todo o aplicativo de front-end React também é executado no servidor. Dessa forma, não precisamos esperar que o JavaScript do lado do cliente crie a marcação; ele é pré-construído no servidor para a URL acessada e enviado ao navegador como HTML. Quando o cliente JavaScript é executado, ele continua de onde o servidor parou. Para apoiar isso, podemos usar o Principal biblioteca, que deve ser usada com Alt.

Primeiro, inicializamos o Flux no servidor usando alt.bootstrap. É possível preencher previamente os armazenamentos do Flux com dados para renderização. Também é necessário decidir qual componente renderizar para qual URL, que é a funcionalidade do lado do cliente Router. Estamos usando a versão singleton de alt, portanto, após cada renderização, precisamos alt.flush() as lojas para limpá-los para outro pedido. Usando o iso add-on, o estado do Flux é serializado para a marcação HTML, para que o cliente saiba onde pegar:

// We use react-router to run the URL that is provided in routes.jsx var getHandler = function(routes, url) { var deferred = Promise.defer(); Router.run(routes, url, function (Handler) { deferred.resolve(Handler); }); return deferred.promise; }; app.use(function *(next) { yield next; // We seed our stores with data alt.bootstrap(JSON.stringify(this.locals.data || {})); var iso = new Iso(); const handler = yield getHandler(reactRoutes, this.request.url); const node = React.renderToString(React.createElement(handler)); iso.add(node, alt.flush()); this.render('layout', {html: iso.render()}); });

No lado do cliente, pegamos o estado do servidor e inicializamos alt com os dados. Em seguida, executamos Router e React.render no contêiner de destino, que atualizará a marcação gerada pelo servidor conforme necessário.

Iso.bootstrap(function (state, _, container) { // Bootstrap the state from the server alt.bootstrap(state) Router.run(routes, Router.HistoryLocation, function (Handler, req) { let node = React.createElement(Handler) React.render(node, container) }) })

Encantador!

Bibliotecas de front-end úteis

Um guia para o ecossistema React não estaria completo sem mencionar algumas bibliotecas de front-end que funcionam especialmente bem com React. Essas bibliotecas lidam com as tarefas mais comuns encontradas em quase todos os aplicativos da web: layouts e contêineres CSS, formulários e botões estilizados, validações, seleção de datas e assim por diante. Não há sentido em reinventar a roda quando esses problemas já foram resolvidos.

React-Bootstrap

Logotipo do React-Bootstrap

Do Twitter Bootstrap framework tornou-se comum, pois é de grande ajuda para todo desenvolvedor web que não quer gastar muito tempo trabalhando em CSS. Principalmente na fase de prototipagem, o Bootstrap é indispensável. Para aproveitar o poder do bootstrap em um aplicativo React, é bom usá-lo com React-Bootstrap , que vem com a sintaxe React agradável e reimplementa os plug-ins jQuery do Bootstrap usando componentes React nativos. O código resultante é conciso e fácil de entender:

Link Link Action Another action Something else here Separated link

Pessoalmente, não posso escapar da sensação de que é assim que o HTML sempre deveria ter sido.

Se você quiser usar a fonte Bootstrap com Webpack, considere usar less-loader ou bootstrap-sass-loader , dependendo do pré-processador de sua preferência. Isso permitirá que você personalize facilmente quais componentes do Bootstrap incluir e também permitirá o uso de variáveis ​​globais LESS ou SASS em seu código CSS.

Roteador React

Logotipo do roteador React

Roteador React tornou-se o padrão de fato para roteamento no React. Ele permite roteamento aninhado, suporte para redirecionamentos, funciona bem com a renderização isomórfica e tem uma sintaxe simples baseada em JSX:

Link

O React Router também fornece um About Users componente que você pode usar para navegação em seu aplicativo, especificando apenas o nome da rota:

active

Existe até uma biblioteca para integração com o React-Bootstrap, então se você estiver usando os componentes do Bootstrap e não quiser configurar o About Users aula sobre eles manualmente o tempo todo, você pode usar react-router-bootstrap e escrever código como este:

import Formsy from 'formsy-react'; import {Input} from 'formsy-react-components'; export default class FormsyForm extends React.Component { enableButton() { this.setState({canSubmit: true}); } disableButton() { this.setState({canSubmit: true}); } submit(model) { FormActions.saveEmail(model.email); } render() { return ( Submit )} }

Nenhuma configuração adicional é necessária. Links ativos cuidarão de si mesmos.

Formsy-React

Trabalhar com formulários pode ser entediante, então vamos obter ajuda do Formy-Reage biblioteca, que nos ajudará a gerenciar validações e modelos de dados. A biblioteca Formsy-React, estranhamente, não inclui as entradas de formulário reais porque os usuários são encorajados a escrever seus próprios (o que é ótimo). Mas se você estiver satisfeito com os comuns, basta usar componentes de reação de formulários . As classes de bootstrap estão incluídas:

import Pikaday from 'react-pikaday'; import Select from 'react-select'; export default class CalendarAndTypeahead extends React.Component { constructor(props){ super(props); this.options = [ { value: 'one', label: 'One' }, { value: 'two', label: 'Two' } ]; } dateChange(date) { this.setState({date: date}); }, selectChange(selected) { this.setState({selected: selected}); }, render() { return ( )} }

Calendário e Typeahead

O calendário e a digitação antecipada são a cereja do bolo de todo kit de ferramentas de IU. Infelizmente, esses dois componentes foram removidos do Bootstrap 3, provavelmente porque são especializados demais para um framework CSS de propósito geral. Felizmente, consegui encontrar substitutos dignos em react-pikaday e reagir-selecionar . Eu testei mais de 10 bibliotecas e essas duas foram consideradas as melhores. Eles são muito fáceis de usar, também:

|_+_|
Quando se trata de React, é uma selva lá fora! Aqui está um mapa para ajudá-lo a encontrar seu caminho. Tweet

Conclusão - React.JS

Neste artigo, apresentei bibliotecas e técnicas que considero algumas das mais produtivas no desenvolvimento web atual. Alguns deles são específicos do React, mas devido à natureza aberta do React, muitos deles podem ser usados ​​em outros ambientes também. O progresso tecnológico às vezes é prejudicado pelo medo das novidades, então espero que este artigo ajude a dissipar as dúvidas sobre React, Flux e os recursos mais recentes do ECMAScript.

React Ecossystem

Se você estiver interessado, pode dar uma olhada no meu exemplo de aplicação construído com essas tecnologias. O código-fonte está disponível em GitHub .

Obrigado por ler!

Relacionado: Práticas recomendadas e dicas do React.js por desenvolvedores do ApeeScape

Robo-conselheiro Risco de portfólio da indústria: eficiência ou redução de cantos?

Processos Financeiros

Robo-conselheiro Risco de portfólio da indústria: eficiência ou redução de cantos?
Hillary Clinton desperta a ira ao chamar os apoiadores de Donald Trump de 'cesta de deploráveis'

Hillary Clinton desperta a ira ao chamar os apoiadores de Donald Trump de 'cesta de deploráveis'

Noticias Do Mundo

Publicações Populares
Nvidia Shield - Uma visão diferente dos consoles de jogos Android
Nvidia Shield - Uma visão diferente dos consoles de jogos Android
Planejamento de sucessão de private equity: o que fazer e o que não fazer
Planejamento de sucessão de private equity: o que fazer e o que não fazer
Representante do Queen's em Londres diz que a realeza apóia o movimento Black Lives Matter
Representante do Queen's em Londres diz que a realeza apóia o movimento Black Lives Matter
Truques de magia indiana que surpreendeu o mundo
Truques de magia indiana que surpreendeu o mundo
Métricas de sobrevivência: familiarizando-se com a taxa de queima de inicialização
Métricas de sobrevivência: familiarizando-se com a taxa de queima de inicialização
 
PM Modi compara o exército indiano ao de Israel: Aqui está o porquê
PM Modi compara o exército indiano ao de Israel: Aqui está o porquê
Um guia para gerenciar dependências de Webpack
Um guia para gerenciar dependências de Webpack
De Khirki a Fathepur e ‘Sambhaji Nagar’, os muitos nomes de Aurangabad
De Khirki a Fathepur e ‘Sambhaji Nagar’, os muitos nomes de Aurangabad
Como Sequel e Sinatra resolvem o problema da API Ruby
Como Sequel e Sinatra resolvem o problema da API Ruby
Caixa de ferramentas do Forecaster: como realizar simulações de Monte Carlo
Caixa de ferramentas do Forecaster: como realizar simulações de Monte Carlo
Publicações Populares
  • como testar uma classe em java
  • o que aconteceu com telefones blackberry
  • @media screen e (largura mínima 321px) e (largura máxima 480px)
  • usos futuros da realidade virtual
  • como depurar vazamento de memória
  • como funciona o c ++
  • dimensões do dispositivo para web design responsivo
Categorias
  • Web Front-End
  • Gestão De Engenharia
  • Ciência De Dados E Bancos De Dados
  • Ascensão Do Remoto
  • © 2022 | Todos Os Direitos Reservados

    portaldacalheta.pt