#VemProReact #JEP #3

#VemProReact

#VemProReact #JEP #2

Arrow Functions

const App = () => (
  <div className="App">
    <header className="App-header">
      <Logo />
      <Text />
      <Link />
    </header>
  </div>
);
const Link = () => (
  <a 
    className="App-link" 
    href="https://reactjs.org" 
    target="_blank" 
    rel="noopener noreferrer"
  >
    Learn React
  </a>
);
const Logo => () => (
  <img src={logo} className="App-logo" alt="logo" />
);
const Text = () => (
  <p>
    Edit <code>src/App.js</code> and save to reload.
  </p>
);

#VemProReact

#VemProReact #JEP #2

Header.js

const App = () => (
  <div className="App">
    <Header>
      <Logo />
      <Text />
      <Link />
    </Header>
  </div>
);
const Header = (props) => (
  <header className="App-header">
    {props.children}
  </header>
);

#VemProReact

#VemProReact #JEP #2

#Desafio!

const Logo = (props) => {
  const imgs = [];

  for (let i = 0; i < props.repeat && i < 6; i++) {
    imgs.push(<img key={i} src={logo} className="App-logo" alt="logo" />);
  }
  
  return (
    <div className="App-logo-container">
      {imgs}
    </div>
  );
};

Logo.defaultProps = {
  repeat: 1
}

Logo.js

#VemProReact

#VemProReact #JEP #2

#Desafio!

.App-logo-container {
  display: flex;
}

.App-logo {
  height: 20vmin;
  pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
  .App-logo {
    animation: App-logo-spin infinite 10s linear;
  }

  .App-logo:nth-child(even) {
    animation-direction: reverse;
  }
}

Logo.css

#VemProReact

#VemProReact #JEP #2

#Desafio!

const App = () => (
  <div className="App">
    <Header>
      <Logo repeat={3} />
      <Text />
      <Link />
    </Header>
  </div>
);

App.js

#VemProReact

#VemProReact #JEP #2

E o tal do Destructuring Assignment?

#VemProReact

Destructuring Assignment

  • É um tipo de declaração de variáveis
  • Permite extrair propriedades específicas de objetos
  • Permite extrair itens específicos de arrays
  • Permite a definição de valores padrão

Exemplos:

const { children } = props;
const [ first, second ] = [ 1, 2 ];
const { limit = 50 } = config;
const [ first, second = 2 ] = [ 1 ];

#VemProReact

Destructuring Assignment

Como declarar variáveis com destructuring assignment?

#VemProReact

Destructuring Assignment

Considerando a declaração abaixo:

Seria, simplesmente, envolver o children entre "{}" e remover o ".children" do objeto props:

const { children } = props;

Na prática:

Nós simplesmente criamos uma variável children e atribuímos o valor de props.children a ela.

const children = props.children;

#VemProReact

Destructuring Assignment

Agora, considerando a declaração abaixo:

Seria, simplesmente, envolver as variáveis first e second entre "[]" e atribuir o array diretamente:

const [first, second] = [ 1, 2, 3, 4, 5 ];

Na prática:

Nós simplesmente criamos duas variáveis (first e second) e atribuímos o valor do primeiro e segundo item do array à elas.

const numbers = [ 1, 2, 3, 4, 5 ];
const first = numbers[0];
const second = numbers[1];

#VemProReact

state

  • Nos permite criar componentes mais inteligentes
  • Ao contrário das props, podemos modificar seus valores
  • É privado, ou seja, só "existe" dentro do componente
  • É totalmente controlado pelo próprio componente
  • Usaremos os states através da hook* useState

Na teoria:

*Hooks são funções utilitárias que podemos usar dentro dos componentes

#VemProReact

state

É uma variável JavaScript que tem um valor inicial e uma função específica para manipular seu contéudo

Na prática:

Exemplo:

import React, { useState } from 'react';

const Text = () => {
  const [code, setCode] = useState('src/App.js')

  return <p>Edit <code>{code}</code> and save to reload.</p>;
}

export default Text;

#VemProReact

state

Como definir o state de um componente usando useState?

#VemProReact

useState

Importamos a função useState do react:

import React, { useState } from 'react';
const [code, setCode] = useState();

Fazemos um destructuring da useState, declarando o state e a função de atualização dele:

E para utilizar:

<p>Edit <code>{code}</code> and save to reload.</p>
const [code, setCode] = useState('src/App.js');

Informamos no parâmetro da useState o valor inicial desejado para o state:

#VemProReact

useState

Como atualizar o state de um componente?

#VemProReact

useState

A função de atualização que declaramos nos permite fazer isto

setCode('src/Logo.js');

Basta chamá-la informando seu novo valor:

Ou, informando uma nova função que tem o state atual como parâmetro e retorna o novo valor:

setCode((code) => code.replace('App', 'Logo'));

#VemProReact

Event handlers

  • Nos permite realizar ações baseados nas interações do usuário
  • São muito semelhantes aos eventos nativos (DOM)
  • São nomeados com camelCase
  • Recebem uma função JavaScript

Exemplos:

const Button = () => <button onClick={() => { console.log('Clicked') }}>Click here!</button>;
const Button = () => {
  const clickHandler = () => {
    console.log('Clicked');
  }

  return <button onClick={clickHandler}>Click here!</button>
}

#VemProReact

Event handlers

Como tratar um evento no componente?

#VemProReact

Event handlers

Declaramos uma função para realizar o tratamento:

const clickHandler = () => {
  console.log('Click');
}

Informamos ao componente/tag qual será o evento "escutado" e atribuímos a função:

<Button onClick={clickHandler}>Click here!</Button>

Simplesmente isto!

Eventos suportados pelo React:

#VemProReact

Dúvidas?

#VemProReact

Atividade!

  1. Remover a prop "repeat" do desafio e recriá-la como um state do componente, com o valor padrão = 1
     
  2. Criar dois botões na tela, um para incrementar e outro para decrementar o repeat. Implementado as funções necessárias
     
  3. Estudar o conceito de Spread Operator

Correção da atividade!

#VemProReact

const App = () => (
  <div className="App">
    <Header>
      <Logo />
      <Text />
      <Link />
    </Header>
  </div>
);

App.js

Correção da atividade!

#VemProReact

const Logo = () => {
  const [repeat, setRepeat] = useState(1);

  const imgs = [];

  for (let i = 0; i < repeat; i++) {
    imgs.push(<img key={i} src={logo} className="App-logo" alt="logo" />);
  }
  
  return (
    <>
      <div className="App-logo-container">
        {imgs}
      </div>
      <div className="App-logo-buttons">
        <button disabled={repeat === 6} onClick={() => setRepeat((repeat) => repeat + 1)}>
          Logo +
        </button>
        <button disabled={repeat === 1} onClick={() => setRepeat((repeat) => repeat - 1)}>
          Logo -
      </div>
    </>
  );
};

Logo.js

Correção da atividade!

#VemProReact

.App-logo-buttons {
  display: grid;
  grid-auto-flow: column;
  column-gap: 20px;
}

.App-logo-buttons > button {
  padding: 5px 10px;
  font-weight: 700;
  border-radius: 5px;
  cursor: pointer;
  outline: none;
}

.App-logo-buttons > button:hover {
  text-decoration: underline;
}

Logo.css

Correção da atividade!

#VemProReact

Mas o que é Spread Operator mesmo?

#VemProReact

Spread Operator

  • É uma sintaxe
  • Faz a atribuição dinâmica de valores
  • Forma mais prática de trabalhar com arrays/objetos

Na teoria:

#VemProReact

Spread Operator

Na prática:

  • É um trecho do código que parece não fazer sentido e começa com "..."
  • Na maioria das vezes, vai estar dentro de um array "[]" ou objeto "{}"
  • Extrai o conteúdo do objeto que segue os "..."

Exemplo:

[...array, 3, 4, 5]
{
    ...myObj,
    prop: newValue
}

#VemProReact

Como usar o spread operator?

Spread Operator

#VemProReact

Considerando a declaração abaixo:

Seria, simplesmente, declarar um novo array, contendo array1 e array2, precedidos por "...":

const array3 = [...array1, ...array2]; // [1, 2, 3, 4]
const array1 = [1, 2];
const array2 = [3, 4];

const array3 = array1.concat(array2); // [1,2,3,4]

Spread Operator

Observe a diferença:

const array3 = [...array1, ...array2]; // [1, 2, 3, 4]
const array3 = [array1, array2]; // [[1, 2], [3, 4]]

#VemProReact

Imagine o seguinte:

Seria, simplesmente, receber o objeto dentro dele mesmo (com "...") e sobrescrever a prop desejada:

const user = {
    first_name: 'Daniel',
    last_name: 'Xavie',
    age: 26
};

user.last_name = 'Xavier';

user.first_name + user.last_name + (user.age) // Daniel Xavier (26)

Spread Operator

Para objetos, seguimos a mesma ideia...

user = {
    ...user,
    last_name: 'Xavier'
};

user.first_name + user.last_name + (user.age) // Daniel Xavier (26)

#VemProReact

Component Lifecycle

Existem 4 situações principais onde manipularemos o componente:

  • Quando o componente é montado
  • Quando acontece qualquer modificação
  • Quando acontece uma modificação específica
  • Quando o componente é desmontado

Nos permite manipular o componente em determinadas situações

Usaremos a hook useEffect para tratar todas essas situações

#VemProReact

useEffect

Executado quando o componente é montado na tela!

Exemplo:

const MyComponent = () => {
  const [name, setName] = useState('');
  
  useEffect(() => {
    console.log('MyComponent mounted');
    
    setName('Daniel');
  }, [])

  return <p><b>My name is:</b> {name}</p>
}

HTML:

console:

#VemProReact

useEffect

Executado quando qualquer prop/state do componente é alterado!

Exemplo:

...

  useEffect(() => {
    console.log('MyComponent updated');
  })

...

HTML:

console:

#VemProReact

useEffect

Dica MUITO IMPORTANTE:

Se você fizer um setState qualquer dentro do useEffect, sem array de dependências, vai acontecer um loop "infinito"

Como o React é "bonzinho", ele vai interromper a execução e te mostrar um belíssimo erro:

#CuidadoComOuseEffect

#VemProReact

useEffect

Executado quando uma prop/state específico do componente é alterado!

Exemplo:

...

  useEffect(() => {
    console.log('MyComponent updated');
    
    console.log('name state changed');
  }, [name])

...

HTML:

console:

#VemProReact

useEffect

Executado quando o componente é desmontado!

Exemplo:

...

useEffect(() => {
  console.log('MyComponent updated');

  return () => {
    console.log('MyComponent unmounted');
  }
})

...

HTML:

console:

#VemProReact

Dúvidas?

#VemProReact

Atividade!

  1. Remover o valor padrão do state repeat e defíni-lo usando useEffect
     
  2. Criar um useEffect para imprimir no console "repeat updated!" toda vez que o valor do repeat mudar
     
  3. Criar um (ou mais) state para contar quantas vezes cada botão foi clicado
     
  4. Exibir a informação acima na tela
     
  5. Estudar o conceito de Template Strings

#VemProReact

Obrigado!

#VemProReact #JEP #3

By Softplan Planejamento e Sistemas

#VemProReact #JEP #3

Destructuring assignment; State; useState; Event handlers; Spread operator; Component lifecycle; useEffect

  • 488