DEV Community

Matheus Almeida
Matheus Almeida

Posted on

O que você precisa saber de JavaScript antes de começar com React?

Está vindo de outra linguagem ou sabe o básico de JavaScript e quer começar a brincar com React?

Esse post é pra você!

JavaScript for React

Nesse texto iremos ver o básico do ES6 que você precisa saber pra escrever um bom código. Os tópicos que serão abordados aqui:

  • Declarando Variáveis (VAR/CONST/LET)
  • Arrow Functions
  • Spread Operator
  • Destructuring Object/Array
  • Template String
  • Classes
  • ~Promises~

Se você já sabe algum dos tópicos sinta-se a vontade pra pular para outro.


Introdução

Antes de começar vamos explicar o que é o ES6.

ECMAScript é uma linguagem de script que forma a base do JavaScript. ECMAScript é padronizado pela ECMA International Standards Organization nas especificações ECMA-262 e ECMA-402

(developer.mozilla.org)

O ES6, ECMAScript 6, é a versão que foi lançada em 2015 e introduziu varias novidades ao JavaScript (JS) que tornaram a linguagem muito mais completa e confiável. Como Classes, Arrow Functions, Variáveis com Escopo e muitas outras novidades. Se você quer utilizar JavaScript em qualquer tipo de ambiente hoje em dia você TEM que saber o básico do ES6.


Declarando Variáveis (VAR/CONST/LET)

No JS o básico que você tem para criar uma variável é utilizando a palavra reservada var. Porém ela tem um problema, ela não é restrita ao escopo na qual ela foi declarada.


function exibeMensagem() {
  var msgForaDoIf = "olá";
  if (msgForaDoIf == "olá") {
    var msgDentroDoIf = "JS";
  }

  console.log(msgForaDoIf);
  console.log(msgDentroDoIf);
}

exibeMensagem();

Quando eu executo a função exibeMensagem o que vocês acham que acontece? Se você acha que só a msgForaDoIf foi imprimir no console e a msgDentroDoIf deu alguma mensagem de erro você… ERROU. Nessa caso ao rodar a função as duas mensagens aparecem na tela, mesmo a msgDentroDoIf ter sido declarada em outro escopo ela se mantém acessível fora dele.

Para resolver isso, no ES6 foi introduzido o let.

function exibeMensagem() {
  let msgForaDoIf = "olá";
  if (msgForaDoIf == "olá") {
    let msgDentroDoIf = "JS";
  }

  console.log(msgForaDoIf);
  console.log(msgDentroDoIf);
}

exibeMensagem();

Nesse segundo caso, assim que você chamar a função ela ira imprimir na tela a mensagem "olá" porém quando ele chega no segundo console.log ele joga um erro na tela informando que a variável msgDentroDoIf não foi definida.

Um outro tipo de declarar variável no ES6 é o const, porém antes vou mostrar mais um exemplo com let.

function exibeMensagem() {
  let msgForaDoIf = "olá";
  if (msgForaDoIf == "olá") {
    msgForaDoIf = "JS";
  }

  console.log(msgForaDoIf);
}

exibeMensagem();

Assim que ele entra no if a variável fora do if tem seu conteúdo alterado para "JS" e imprime a mesma no console. O const vem para dar uma alternativa a esse tipo de declaração.

function exibeMensagem() {
  const msgForaDoIf = "olá";
  if (msgForaDoIf == "olá") {
    msgForaDoIf = "JS";
  }

  console.log(msgForaDoIf);
}

exibeMensagem();

Assim que tentamos alterar o valor de uma variável que foi declarada como const você recebe uma mensagem de erro que está tentando reatribuir um valor à uma variável constante. No meu uso normal eu sempre tento me manter utilizando const em todos os casos, alguns eu recaio para o let, pois assim você consegue um código mais conciso e que é facilmente testável depois. Mas uma coisa que acho legal é evitar ao máximo o uso de var, não faz sentido utilizar ele com o let e const fazendo muito mais sentido.

Outro detalhe pequeno do const é que assim que você declara uma variável constante você já tem que inicializar ela com alguma coisa.

const a = "olá"; // Declaração correta

const b; // Irá jogar um erro

Obs: Todos esses códigos acima você pode testar abrindo o console do seu navegador e colando ele 😁


Arrow Function

Esse item tem algumas nuances que o fazem ser mais interessantes de se utilizar em alguns casos. Mas antes, vamos mostrar uma comparação de declarações de função no JS.

function fn1(x) {
  console.log("Função 1:", x);
}

const fn2 = function (x) {
  console.log("Função 2:", x);
}

const fn3 = (x) => {
  console.log("Função 3:", x);
}

const fn4 = x => console.log("Função 4:", x);

fn1(1);
fn2(2);
fn3(3);
fn4(4);

Todas as declarações de funções acima funcionam. A primeira (fn1) é o modo mais comum de você declarar uma função em seu código. As outras 3 declarações que são atribuídas à uma variável são chamadas de função anónima, pois ela não possui um nome. As funções fn3 e fn4 são as que chamamos de Arrow Functions, nesse caso elas só estão diferindo pela maneira de escrever mas funcionam 100% da mesma maneira.

Vantagens de utilizar Arrow Functions:

  • Sintaxe menos verbosa que a declaração tradicional de função;
  • A variável this, que indica o escopo que a função está sendo executada, na Arrow Function já é preenchida com o this do escopo que ela foi criada. Com uma função normal você teria que utilizar um .bind() ou passar o this como um parâmetro para o próximo escopo.

Vamos ver alguns exemplos:

function Exemplo(param) {
  this.param = param;
}

Exemplo.prototype.exemploArray = function () {
  const vetor = ["M", "u", "n", "d", "o"];

  return vetor.map(function(elemento) {
    return this.param + " " + elemento
  })
};

const instanciaExemplo = new Exemplo("Olá");

instanciaExemplo.exemploArray();

O resultado esperado com o código acima é que ao executar o exemploArray seja retornado ["Olá M", "Olá u", …, "Olá o"] mas nesse exemplo o que ocorre é que o valor de this na função que está sendo executada é o this da função vetor.map e dentro dele não existe param assim retornando ["undefined M", "undefined u", …, "undefined o"].

Para resolver isso, o modo mais fácil é substituir a função que estamos passando para o .map() por uma Arrow Function.

function Exemplo(param) {
  this.param = param;
}

Exemplo.prototype.exemploArray = function () {
  const vetor = ["M", "u", "n", "d", "o"];

  return vetor.map((elemento) => {
    return this.param + " " + elemento
  })
};

const instanciaExemplo = new Exemplo("Olá");

instanciaExemplo.exemploArray();

Você vai utilizar bastante isso para passar funções de um componente pai para um filho dentro do React.


Spread Operator

O spread operator (…), esses 3 pontinhos ai mesmo, é muito utilizado na hora de escrever a sua função para receber parâmetros que não foram definidos. No React tem um caso interessante de uso para quando vc está fazendo o seu componente com base em outro você pode definir as funcionalidades extras do seu componente e receber todos os outros possíveis do componente base utilizando o spread operator.

A seguir alguns casos genérico que você vai poder utilizar o spread operator com arrays e funções:

function fn(x, y, z) {
  console.log(x, y, z);
}

const args1 = [0, 1, 2];
fn(...args1);

const args2 = [1, 2];
fn(0, ...args2);

fn(0, ...[1], 2);

// Concatenando Arrays
const a = [1];
const b = [0, ...a, 2];
fn(...b);

Agora alguns casos com objetos:

const pessoaA = {nome: "Matheus", idade: 23};

const githubA = {usuario: "matAlmeida"};

const pessoaAcomGithubA = {...pessoaA, ...githubA};

console.log(pessoaA);
console.log(githubA);
console.log(pessoaAcomGithubA);

const pessoaAVelha = {...pessoaA, idade: 83};
console.log(pessoaAVelha);

No exemplo acima é possível perceber que você consegue juntar 2 objetos e modificar um objeto sem destruir o registro anterior dele utilizando o spread operator, esses são os principais usos dele.


Destructuring Object/Array

A desestruturação é uma das operações mais úteis e que deixa o seu código muita mais enxuto e você olha para ele e consegue entender rapidamente o que está acontecendo ali.

Abaixo um exemplo de uso da desestruturação na criação de funções:


function fn1(objeto) {
  console.log(objeto.nome, objeto.idade);
}

const pessoaA = {nome: "Matheus", idade: 23};

fn1(pessoaA);

function fn2({nome, idade}) {
  console.log(nome, idade);
}

fn2(pessoaA);

Como você consegue ver no código acima a fn2 é muito mais concisa e é só bater o olho para saber o que o objeto que você está passando precisa conter.
Agora outros exemplos declarando variáveis utilizando desestruturação:

const pessoaA = {nome: "Matheus", idade: 23};

const { nome } = pessoaA;

console.log(nome);

const alfabeto = ["a", "b", "c", "d"];

const [letraA, letraB, ...outrasLetras] = alfabeto;
const [letraC, letraD] = outrasLetras;

console.log(letraA, letraB, letraC, letraD);

Você vai usar bastante isso pra simplificar o seu código quando estiver recebendo algum objeto/array mas só vai precisar de certos elementos.


Template String

Agora outra adição muito interessante do ES6 é o Template String, com ele você consegue "concatenar" variáveis em uma string de um jeito muito mais elegante do que o de "somar" uma string com uma variável.

const myName = "Matheus";

console.log(`O seu nome é: ${myName}!`); // "O seu nome é: Matheus!"

Como você pode notar a sintaxe é um pouco diferente, no lugar da utilização de aspas, simples ou dupla, é utilizado o backtick também conhecido como crase indicando que aquela string é uma Template String e em adição temos a sintaxe de ${nome_da_variável} que é onde você adiciona a sua variável.
Outro ponto interessante de prestar atenção é que ele mantém quebras de linha que você escreve na declaração da string.

console.log("
  Oi
  Meu
  Nome
  É
  Matheus
");
// Console: ERRO DE SINTAXE

console.log(`
  Oi
  Meu
  Nome
  É
  Matheus
`);
// Console:
// "Oi
//  Meu
//  Nome
//  É

Acredito que só isso seja necessário pra entender o que é Template String.


Classes

Classes acredito que seja bem rápido, é praticamente igual em todas linguagens OO, a única novidade aqui é que antes dessa versão do ES não existia esse conceito no JavaScript. Vale lembrar que praticamente tudo que você trabalha no JS é um "objeto", porém não existiam classes, a galera trabalhava um conceito parecido fazendo o uso dos Prototypes, não é mais utilizado na maioria dos casos, ele funcionava de forma parecida aos Extensions no Kotlin.

class Pessoa {
  outroNome = "Venkman";

  constructor(name) {
    this.name = name;
  }

  printName() {
    console.log(this.name);
    console.log(this.outroNome);
  }

  printNameAF = () => {
    console.log(this.name);
    console.log(this.outroNome);
  };
}

Nesse código você consegue ver que é possível ter um construtor, propriedades da classe que podem ser declaradas em qualquer parte do código e fora de funções também. Temos o this para acessar as propriedades locais da classe.

Um ponto importante de falar é que não existem classes privadas no JavaScript, uma convenção que a comunidade em geral toma é declara funções/propriedades que deveriam ser privadas com um underline "_" na frente da declaração, se você estiver utilizando alguma classe e tiver algo com esse underline na frente tente não mexer pois pode causar comportamentos indesejáveis.


Promises

Eu ia escrever sobre Promises, mas tem um post muito melhor explicado sobre o assunto feito pelo mestre Roberto Achar, nele é explicado um pouco sobre Promises e o foco é explicar o Async/Await. Vale a leitura:

Entenda tudo sobre Async/Await


Tem muitos mais outros pontos que poderíamos abordar aqui nesse post mas ele ficaria muito extenso. Tentei colocar somente o básico mesmo, se você já tem uma pequena base de javascript acredito que dê pra pegar pelo menos a ideia de cada uma das funcionalidades apresentadas.

Qualquer dúvida sinta-se à vontade para me chamar no twitter ou procurar pelo google, existe muito material muito explicativo, recomento o site da documentação do JS feito pela Mozilla.

Vou tentar escrever pelo menos um post por mês durante esse ano, não prometo nada rs.

Top comments (0)