
Já não é novidade que o React tem dominado diversas empresas por diversos motivos, um deles é a facilidade de utilizar a mesma lógica tanto na parte web quanto na parte mobile (React Native), sabendo disso nós preparamos 12 bibliotecas que você deveria considerar em usar nos seus projetos.
Nossa lista foi dividida em Design, funcionalidades legais, estilo de código e pagamento, simbora!
Libs de Design 👨🏻🎨
1 – Ant design: Esse framework é o segundo mais popular na parte de UI (User Interface), ele é super simples de implementar, bem documentado, com aspectos minimalistas e super completo.
Talvez ele não atenda todos os casos, mas se você tem algo para fazer que é super comum, você pode dar uma chance para o framework e fazer isso usando o Ant Design.
Veja um exemplo de um site feito com o Ant Design:
Supondo que eu queira fazer algo assim:
Poderíamos fazer um botão nesse tal de 🐜 Design, desse modo:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
const { Button } = antd; ReactDOM.render( <> <Button type="primary">🐜</Button> <Button>OneBitCode</Button> <Button type="dashed">Botão tracejado</Button> <br /> <Button type="text">Botão sem borda</Button> <Button type="link">Botão do tipo link</Button> </>, mountNode, ); |
2 – Material-UI: Esse belíssimo framework foi desenvolvido pela Google, ele é oferecido para diversas aplicações, seja em React, HTML puro, Vue, entre outros.
Ele permite você criar sistemas extremamente completos e bonitos, repetir diversos comportamentos padrões que são usados pelo a Google em seus sites e é o framework mais popular de UI do React.
Um exemplo pronto na parte de templates do Material UI:
Vamos supor que eu queira fazer algo assim, utilizando o MaterialUI para deixar os componentes já estilizados:
O nosso código seria esse:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
//Importo as bibliotecas padrões import React from 'react'; import { makeStyles } from '@material-ui/core/styles'; import Button from '@material-ui/core/Button'; //Coloco margem em todos os elementos da página const useStyles = makeStyles((theme) => ({ root: { '& > *': { margin: theme.spacing(1), }, }, })); // Exporto os botões criados export default function ContainedButtons() { const classes = useStyles(); return ( <div className={classes.root}> <Button variant="contained">One</Button> <Button variant="contained" color="primary"> Bit </Button> <Button variant="contained" color="secondary"> Code </Button> <Button variant="contained" disabled> Desabilitado </Button> <Button variant="contained" color="primary" href="#contained-buttons"> Link </Button> </div> ); } |
Link do exemplo no CodeSandBox
Libs com Funcionalidades legais 😁
3 – Enzyme (Test): Talvez você não saiba ou não esteja acostumado com a idéia mas quando a gente começa a ganhar algum tipo de senioridade no desenvolvimento de software, é preciso que a gente teste o que nós fizemos.
Por dois bons motivos:
– Para sabermos se de fato pensamos nos casos certos e codamos para funcionar nesses casos.
– E caso um desenvolvedor mexa numa parte do código, nós saberemos se os nossos testes quebraram (falharam).
É aí que entre o Enzyme que é uma biblioteca para o Javascript que permite testarmos
Talvez fique um pouco mais fácil de entender vendo na prática, vamos lá:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
//Importamos as bibliotecas necessárias para rodar os testes import React from 'react'; import { expect } from 'chai'; import { shallow } from 'enzyme'; import sinon from 'sinon'; //Importamos os componentes que vamos testar import MeuComponente from './MeuComponente'; import Botao from './Botao'; //Descrevo um contexto de teste, nesse caso <MeuComponente /> poderia ser //Testando a tela inicial da aplicação, exemplo.. describe('Testando a tela inicial da aplicação do <MeuComponente />', () => { //descrevo o que o teste está fazendo it('renderiza vários componentes chamados Botao', () => { //uso uma linguagem específica do teste, shallow e o componente que //eu quero ficar de olho <MeuComponente /> const wrapper = shallow(<MeuComponente />); //verifico se dentro do wrapper eu encontro 3 componentes do tipo Botao //wrapper = [<Botao />, <Botao />, <Botao />] expect(wrapper.find(Botao)).to.have.lengthOf(3); }); //Acho que ficou bem claro o que esse código aqui faz, certo ? it('Simula que o botão foi clicado', () => { const onButtonClick = sinon.spy(); const wrapper = shallow(<Botao onButtonClick={onButtonClick} />); wrapper.find('button').simulate('click'); expect(onButtonClick).to.have.property('callCount', 1); }); }); |
Com isso, se um novo dev remover um dos botões, esse teste acima, iria falhar e com isso nós iriamos conseguir ver se esse é o novo comportamento desejado ou somente uma falha de implementação.
4 – React Hook Form: Ao começar a programar e fazer algum tipo de aplicação, já deve ter pensado em fazer um formulário, certo? E com certeza já pensou, poxa isso é algo tão comum, será que existe uma biblioteca que me ajuda a fazer isso ? A resposta é SIM!!! 🙌🏻
Vamos ver um exemplo a seguir:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
import React from "react"; import { useForm } from "react-hook-form"; export default function App() { const { register, handleSubmit, watch, errors } = useForm(); const onSubmit = data => console.log(data); console.log(watch("esporteFavorito")); // vai ficar observando o valor passando o campo "name" do seu input return ( {/* "handleSubmit" vai validar seus inputs antes de chamar o onSubmit */} <form onSubmit={handleSubmit(onSubmit)}> {/* salva o seu input passando a função register */} <input name="esporteFavorito" defaultValue="test" ref={register} /> {/* incluí as validações necessárias para o seu form ou usa o padrão do HTML */} <input name="exampleRequired" ref={register({ required: true })} /> {/* errors serão retornados quando seu input for inválido */} {errors.exampleRequired && <span>This field is required</span>} <input type="submit" /> </form> ); } |
https://onebitcode.com/dating-profiles-for-men/
free dating site which has the largest population of member
5 – React DnD (drag and drop): Essa biblioteca é bem interessante, o React DnD é um conjunto bem consistente de utilitários para o React que te ajuda a construir interfaces mais complicadas que precisam da funcionalidade Drag and Drop (Arrastar e soltar), como por exemplo o Trello ou o Storify.
Se por exemplo, nós quiséssemos fazer um quadro onde temos nomes e desejamos arrastar esses nomes, poderíamos fazer algo parecido com isso:
dating site aucklandhttps://onebitcode.com/kid-dating-sites-12-under/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
//No nosso componente principal, vamos encapsular com o DnDProvider function App() { return ( <div className="App"> <DndProvider backend={HTML5Backend}> <Example /> </DndProvider> </div> ) } // No nosso componente Example, iriamos fazer algo assim: import React, { useState, useCallback } from 'react' // Vamos construir o estilo do card import { Card } from './Card' // permite movermos o nosso card na tela, baseado no index import update from 'immutability-helper' const style = { width: 400, } export const Container = () => { { const [cards, setCards] = useState([ { id: 1, text: 'OneBitCode', }, { id: 2, text: 'Matheus Mello', }, { id: 3, text: 'Trello Cards', } ]) const moveCard = useCallback( (dragIndex, hoverIndex) => { const dragCard = cards[dragIndex] setCards( update(cards, { $splice: [ [dragIndex, 1], [hoverIndex, 0, dragCard], ], }), ) }, [cards], ) const renderCard = (card, index) => { return ( <Card key={card.id} index={index} id={card.id} text={card.text} moveCard={moveCard} /> ) } return ( //retornamos um Array de cartas com a função renderCard <> <div style={style}>{cards.map((card, i) => renderCard(card, i))}</div> </> ) } } |
6 – Recoil: Quando a sua aplicação começar a ficar maior e com mais responsabilidades, nós normalmente queremos não ter nenhuma dor de cabeça gerenciando o estado da aplicação e é exatamente para isso que o Recoil serve, vamos fazer um exemplo bem simples para vermos como funciona:
To brincando!! Aqui na OneBitCode nós já fizemos um tutorial bem completo para vocês usarem o Recoil, passo a passo, da uma olhada.
7 – React 360: Se você já teve interesse de criar algo usando as experiências 360° que são oferecidas em aplicativos como por exemplo o Google Street View, o React 360 pode te ajudar nisso.
Os exemplos normalmente são bem grandes, porém é possível vermos um pouquinho do que é que dá pra criar e também como ficaria o código final:
Se quiséssemos fazer uma “sala” com uma ação no meio da sala, poderíamos fazer algo parecido com isso:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
... render() { // Temos o título do lugar atual const currentTitle = this.props.currentScene.title; // o título do próximo local que queremos ir const nextTitle = this.props.nextScene.title; //a tela só é mostrada se toda transição e o pré carregamento já tiver terminado const showScreen = !!(!this._preloading && !this.state.inTransition && this.props.currentScene.screen); return ( <View style={[styles.container, this.state.inTransition && {opacity: 0}]}> <Text style={styles.title}> {currentTitle} </Text> {/* Devemos definir a tela onde o usuário está */} <MediaAppTemplateVideoScreen player={this._players.screen._player} style={styles.screen} visible={showScreen} /> {/* Definimos o botão para a próxima tela */} <MediaAppTemplateInfoButton onClick={this._onClickNext} text={`Go To: ${nextTitle}`} width={300} /> </View> ); } } ... |
8 – Firebase: O firebase não é só uma mão na roda, talvez já seja o próprio carro Tesla, automático com I.A. pra você, sério.
Se você conhece um pouco sobre o firebase sabe que eu estou falando a verdade e se não conhece, sem problemas, hoje vou mostrar a pontinha do iceberg.
Com o firebase é possível ter integrações com: Google Ads, AdMob, Google Marketing Platform, Play Store, BigQuery, Slack, Jira, PagerDuty e mais.
O firebase basicamente é um serviço que oferece uma super estrutura para você poder focar no aplicativo e menos na infraestrutura.
Porém vale lembrar que com o passar do tempo, o Firebase tem ganhado maturidade e agora oferece serviços de testes A/B, aprendizado de máquina, análise de performance do app, estabilidade dos serviços, autenticação e outras funcionalidades.
Vamos ver um código simples (de autenticação), que já da pra entender o que podemos fazer usando o firebase:
Basicamente o primeiro passo é criar uma conexão do nosso Aplicativo/Site com o serviço do firebase e pra isso precisamos somente instalar a dependência e colocar as credenciais no nosso projeto:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
//importamos a biblioteca do firebase import app from 'firebase/app'; import 'firebase/auth'; // criamos nosso objeto de configuração const config = { apiKey: *****************, authDomain: *****************, databaseURL: *****************, projectId: *****************, storageBucket: *****************, messagingSenderId: *****************, }; // exportamos essa classe para ser usado no nosso projeto class Firebase { constructor() { app.initializeApp(config); this.auth = app.auth(); } resetDePassword = email => this.auth.sendPasswordResetEmail(email); } export default Firebase |
Agora com o Firebase configurado, precisamos encapsular nossa classe principal utilizando o Firebase para disponibilizar as suas funções para toda a aplicação, então podemos fazer isso:
Vamos primeiro criar um contexto para o firebase:
1 2 3 4 5 6 |
import React from 'react'; const FirebaseContext = React.createContext(null); export default FirebaseContext; |
Agora vamos usar esse contexto na nossa aplicação
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import React from 'react'; import ReactDOM from 'react-dom'; //Um componente App com a nossa aplicação Web import App from './componentes/App'; //Os componentes do Firebase que criamos import Firebase, { FirebaseContext } from './componentes/Firebase'; //Permitindo o Firebase ficar visível para nossa aplicação ReactDOM.render( <FirebaseContext.Provider value={new Firebase()}> <App /> </FirebaseContext.Provider>, document.getElementById('root'), ); |
E depois disso fica fácil oferecer a funcionalidade de resetar a senha, através do email:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
onSubmit = event => { //email que está armazenado no nosso componente const { email } = this.state; //o Objeto do firebase que está disponível para toda a aplicação através do props this.props.firebase .doPasswordReset(email) .then(() => { console.log('Email de reset de senha enviado com sucesso'); }) .catch(error => { console.log('Algo de errado não está certo'); }); event.preventDefault(); }; |
Libs de Estilo de código 🧙🏻
9 – ES-lint: Essa nossa biblioteca ES-lint é usada para corrigir bugs e sugerir melhorias no nosso código.
Talvez você não saiba, mas existe diversos padrões que podem ser usados ao programar em JavaScript, padrões esses que podem ser determinados pelo lugar onde você trabalha, pela comunidade ou por um orgão como é o caso do Ecma International.
A minha opinião sobre o uso do ES-lint é basicamente que em projetos da empresa ou open source, onde tem diversos devs, se todos usarem as mesmas configurações no ES-lint nos seus editores você acabará tendo menos divergências no código produzido.
Então vamos ver um exemplo:
Primeiro você precisa instalar a biblioteca e executar a configuração do eslint:
1 2 3 |
// No seu terminal na pasta do seu diretório eslint --init |
Depois disso você deve criar um arquivo .eslintrc.js ou .yml ou .json, com as regras que você deseja configurar seu projeto, no meu caso estou dizendo que o projeto não pode ter console espalhado pelo código.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
//.eslintrc.json //lembrando que você pode usar a string ou numero para validar a regra //"off" or 0 - desliga a regra //"warn" or 1 - a regra se torna um aviso porém não altera o código //"error" or 2 - a regra se torna um erro { "rules": { "no-console": 2 } } |
Pronto é isso, agora com o .eslintrc.json configurado no nosso projeto, sempre que houver um console perdido no código, ele vai acusar de erro.
10 – Prettier: O Prettier (“mais bonito”) como o nome já diz, tem o intuito de deixar o seu código mais bonito, baseado em padrões e convenções de programação.
Vamos ver um caso onde o Prettier pode me ajudar a formatar meu código para ficar mais legível:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
function OlaMundo({mensagemDeBoasVindas = "ola", mundo = '"OneBitCode"', silent = false, onMouseOver,}) { if(!mensagemDeBoasVindas){return null}; // TODO: Arrumar essa conta let num = Math.floor (Math.random() * 1E+7).toString().replace(/\.\d+/ig, "") return <div className='OlaMundo' title={`Você é o visitante número ${ num }`} onMouseOver={onMouseOver}> <strong>{ mensagemDeBoasVindas.slice( 0, 1 ).toUpperCase() + mensagemDeBoasVindas.slice(1).toLowerCase() }</strong> {mensagemDeBoasVindas.endsWith(",") ? " " : <span style={{color: '\grey'}}>", "</span> } <em> { mundo } </em> { (silent) ? "." : "!"} </div>; } |
Com o Prettier:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
function OlaMundo({ mensagemDeBoasVindas = "ola", mundo = '"OneBitCode"', silent = false, onMouseOver, }) { if (!mensagemDeBoasVindas) { return null; } // TODO: Arrumar essa conta let num = Math.floor(Math.random() * 1e7) .toString() .replace(/\.\d+/gi, ""); return ( <div className="OlaMundo" title={`Você é o visitante número ${num}`} onMouseOver={onMouseOver} > <strong> {mensagemDeBoasVindas.slice(0, 1).toUpperCase() + mensagemDeBoasVindas.slice(1).toLowerCase()} </strong> {mensagemDeBoasVindas.endsWith(",") ? ( " " ) : ( <span style={{ color: "grey" }}>", "</span> )} <em>{mundo}</em> {silent ? "." : "!"} </div> ); } |
Libs de Pagamentos 💰
11 – Paypal: Você já deve ter desejado receber dinheiro com a sua aplicação ou até mesmo integrar um meio de pagamento com um serviço existente, é nesse momento que você pode cogitar em usar o Paypal, a integração dele na verdade é com o JavaScript, mas usaremos no nosso exemplo para um componente feito em React.
Basicamente o processo da integração com o Paypal funciona assim:
Vamos pegar as credenciais, vamos criar um botão com a ação de compra usando nossas credenciais e depois disso vamos criar uma função de retorno (chama-se também callback) para informar ao usuário o sucesso da compra.
Pegando as credenciais:
Link do Paypal para desenvolvedores
1 2 3 4 5 6 7 8 9 10 11 12 |
// No site do paypal, na aba developer podemos pegar no key const AMBIENTE = { sandbox: "SUA_CHAVE_DE_TESTE", production: "SUA_CHAVE_DE_PRODUÇÃO" }; const AMBIENTE_ATUAL = process.env.NODE_ENV === "production" ? AMBIENTE.production : AMBIENTE.sandbox; |
Agora vamos criar nossas 2 funções :
Uma que criar o pedido.
Ao finalizar o pagamento, ela vai saber informar ao usuário o sucesso da compra.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
criarPedido = (data, actions) => { return actions.order.create({ purchase_units: [ //estou criando um produto, com o preço de 100 reais { description: "Meu Produto", amount: { currency_code: "BRL", value: 100 } } ] }); }; compraAprovada = (data, actions) => { actions.order.capture().then(details => { const dadosDePagamento = { payerID: data.payerID, orderID: data.orderID }; // com o pagamento efetuado, agora vou mostrar a mensagem de sucesso // e remover os botões de pagamento console.log("Pagamento aprovado: ", dadosDePagamento); this.setState({ mostrarBotoes: false, foiPago: true }); }); }; |
Vamos agora criar nosso componentes que vão usar essas funções:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
import React from "react"; import ReactDOM from "react-dom"; import scriptLoader from "react-async-script-loader"; import ImagemDoProduto from "../assets/img/produto_incrivel.jpg"; import Spinner from "./Spinner"; const AMBIENTE = { sandbox: "SUA_CHAVE_DE_TESTE", production: "SUA_CHAVE_DE_PRODUÇÃO" }; const AMBIENTE_ATUAL = process.env.NODE_ENV === "production" ? AMBIENTE.production : AMBIENTE.sandbox; let BotaoPayPal = null; class BotaoPayPal extends React.Component { constructor(props) { super(props); //variaveis que vão controlar os botões de compra e a mensagem de sucesso this.state = { mostrarBotoes: false, carregando: true, foiPago: false }; window.React = React; window.ReactDOM = ReactDOM; } //funções que vão permitir comprar o produto criarPedido = (data, actions) => { return actions.order.create({ purchase_units: [ //estou criando um produto, com o preço de 100 reais { description: "Meu Produto", amount: { currency_code: "BRL", value: 100 } } ] }); }; compraAprovada = (data, actions) => { actions.order.capture().then(details => { const dadosDePagamento = { payerID: data.payerID, orderID: data.orderID }; // com o pagamento efetuado, agora vou mostrar a mensagem de sucesso // e remover os botões de pagamento console.log("Pagamento aprovado: ", dadosDePagamento); this.setState({ mostrarBotoes: false, foiPago: true }); }); }; render() { const { mostrarBotoes, carregando, foiPago } = this.state; return ( <div className="main"> {carregando && <Spinner />} {mostrarBotoes && ( <div> <div> <h2>Items: Meu Produto</h2> <h2>Valor total da compra R$100</h2> </div> <BotaoPayPal criarPedido={(data, actions) => this.criarPedido(data, actions)} compraAprovada={(data, actions) => this.compraAprovada(data, actions)} /> </div> )} {foiPago && ( <div className="main"> <img alt="Meu Produto" src={ImagemDoProduto} /> <h2> Mensagem de sucesso </h2> </div> )} </div> ); } } export default scriptLoader(`https://www.paypal.com/sdk/js?client-id=${AMBIENTE_ATUAL}`)(BotaoPayPal); |
Algumas partes do código foram omitidas para diminuir tudo que foi digitado, mas a ideia principal aqui é mostrar o quão simples pode ser começar a vender algo utilizando React como framework de frontend.
12 – Stripe elements (🇧🇷Beta 🇧🇷): O Stripe é um serviço que tem crescido muito no mundo todo, atualmente ele está em versão beta no Brasil, somente alguns usuários podem utilizar ele para fazer as vendas porém como já é conhecido em diversos países, nós decidimos mostrar como você futuramente poderá implementar um formulário de pagamento:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
import React from 'react'; import ReactDOM from 'react-dom'; import {loadStripe} from '@stripe/stripe-js'; import { CardElement, Elements, useStripe, useElements, } from '@stripe/react-stripe-js'; // Formulário de Pagamento const CheckoutForm = () => { const stripe = useStripe(); const elements = useElements(); // Ao clicar em pagar, vamos efetuar o pagamento usando o tipo cartão // pegando o componente Card que o próprio Stripe dá const handleSubmit = async (event) => { event.preventDefault(); const {error, paymentMethod} = await stripe.createPaymentMethod({ type: 'card', card: elements.getElement(CardElement), }); }; return ( <form onSubmit={handleSubmit}> {/* Componentes padrões do próprio Stripe */} <CardElement /> <button type="submit" disabled={!stripe}> Pagar </button> </form> ); }; //Chave para pagamento const stripePromise = loadStripe('**************'); const App = () => ( {/* Atrelar a chave do Stripe ao formulário */} <Elements stripe={stripePromise}> <CheckoutForm /> </Elements> ); ReactDOM.render(<App />, document.body); |
A ideia deles é basicamente facilitar todo o código de pagamento e só deixar você gerenciar o valor e meio de pagamento, depois disso eles sabem lidar com a compra baseado na sua chave da API.
Conclusão
Nesse artigo é possível ver que existem diversas bibliotecas para resolver problemas comuns no desenvolvimento web, seja na criação de formulários, no meio de pagamento, envio de recuperação de senha e em várias outras situações.
Você não precisa ficar inventando a roda toda vez, inclusive, se você gostar de alguma biblioteca, sinta-se livre para contribuir com o código dela, fazendo pull requests nos seus repositórios públicos.
Obrigado por ler este artigo, se você gostou dele, compartilhe com seus amigos, isso nos ajuda e motiva a levar mais conhecimento a mais pessoas. Se você quiser contribuir com sua opinião, estarei de olho nos comentários, 👀.
Até a próxima e um grande abraço,
Matheus Mello
Programador(a), uma pergunta importante!
Você sente verdadeiramente que é um Programador(a) completo(a)?
Por muito tempo eu fiquei em dúvida se eu estava pronto ou não e essa insegurança me levou a pesquisar profundamente sobre o que realmente é necessário para ser um programador web completo.
Depois de fazer muitos treinamentos, ler muitos livros, conversar com outros desenvolvedores, ir a eventos e até trabalhar em empresas do Brasil e do exterior foi que eu pude encontrar as bases fundamentais para ser um programador Web com confiança (sem medo de buscar jobs e assumir grandes projetos).
Eu peguei todo esse conhecimento e somei com toda a didática que eu aprendi criando cursos e tutoriais que são acessados por milhares de pessoas todos os meses e criei um treinamento chamado Programador Full Stack Javascript.
Nele eu vou te mostrar o ‘caminho das pedras’, ou seja, o essencial para você dominar a programação web, se sentir mais completo(a) e conseguir o seu tão merecido Job de respeito.
Então se você quer evoluir de verdade (sem perda de tempo), clica no link abaixo e conheça o treinamento agora.
Link: Programador Full Stack Javascript em 8 semanas ->