Aula 07 – React – Utilizando hooks no código

Aula 07 – React – Utilizando hooks no código

Tutorial React

Tutorial React

Voltar para página principal do blog

Todas as aulas desse curso

Aula 06                        Aula 08

Se gostarem do conteúdo dêem um joinha 👍 na página do Código Fluente no
Facebook

Esse é o link do código fluente no Pinterest

Meus links de afiliados:

Hostinger

Digital Ocean

One.com

Melhore seu NETWORKING

Participe de comunidades de desenvolvedores:

Fiquem a vontade para me adicionar ao linkedin.

E também para me seguir no GITHUB.

Ah, se puder, clica na estrela nos meus repositórios pra dá uma força ao meu perfil no GITHUB

Código da aula:

https://github.com/toticavalcanti/tutorial-react/tree/tic_tac_toe_with_hooks

Link da documentação oficial:

https://reactjs.org/tutorial/

Aula 07 – React – Utilizando hooks no código

Primeiros passos com React Hooks

Antes de começar a refatorar o código do joguinho da velha para usar componente funcional com hooks, vamos falar um pouquinho sobre eles.

A equipe do React apresentou o React Hooks ao mundo na React Conf no final de outubro de 2018.

No início de fevereiro de 2019, finalmente chegou o React v16.8.0. e com ele a possibilidade de usar os hooks.

Os hooks fornecem uma forma de construir componentes funcionais com estado, assim como os componentes baseados em classe têm.

Possibilita a utilização dos métodos de ciclo de vida, permitindo que você evite usar componentes de classe e tenha um código mais modular e legível.

Mas, porque é melhor usar componentes funcionais ao invés de baseados em classes?

  • O código fica mais fácil de ler, de entender, mais fácil de raciocinar e de testar.
  • Você vai precisar escrever menos código;
  • A equipe do React diz que pode haver um aumento de desempenho para componentes funcionais em futuras versões do React.

Agora, em casos onde seu componente precise de muitas funcionalidades, e manter muitos estados, use classes.

O Facebook, criador do React, recomenda oficialmente o uso de componentes funcionais sempre que possível.

Voltando ao código

No código do jogo da velha, temos só o Game com propriedades, o Square e o Board não tem.

Na inicialização, os campos do Board são preenchidos com null, quando o Game passa para ele via props (current.squares) a lista history na posição zero, que é o tabuleiro vazio.

O estado do Game na inicialização é esse: tabuleiro vazio, isto é, o current com tudo null, stepNumber com zero e o xIsNext como true.
A medida que o jogo vai acontecendo, os estados do Game vão sendo atualizados e renderizados na tela.

Código do Tic Tac Toe utilizando hooks e o componente Game e Board como funcional.


import React, { useState } from "react";
import ReactDOM from "react-dom";
import "./tic-tac-toe.css";

const Square = props => {
  return (
    <button
      className="square"
      onClick={props.onClick}
    >
      {props.value}
    </button>
  );
};

const Board = props => { 
  const renderSquare = i => {
    return (
      <Square
        value={props.squares[i]}
        onClick={() => props.onClick(i)}
      />
    );
  };

  return (
    <div>
      <div className="board-row">
        {renderSquare(0)}
        {renderSquare(1)}
        {renderSquare(2)}
      </div>
      <div className="board-row">
        {renderSquare(3)}
        {renderSquare(4)}
        {renderSquare(5)}
      </div>
      <div className="board-row">
        {renderSquare(6)}
        {renderSquare(7)}
        {renderSquare(8)}
      </div>
    </div>
  );
};

const Game = props => {
  const initialHistory = [
    { squares: Array(9).fill(null) }
  ];
  const [history, setHistory] = useState(initialHistory);
  const [xIsNext, setXIsNext] = useState(true);
  const [stepNumber, setStepNumber] = useState(0);

  const handleClick = i => {
    const slicedHistory = history.slice(0, stepNumber + 1);
    const finalStepInSlicedHistory = slicedHistory[slicedHistory.length - 1];
    const newSquares = [...finalStepInSlicedHistory.squares];

    const winnerDeclared = Boolean(calculateWinner(newSquares));
    const squareAlreadyFilled = Boolean(newSquares[i]);
    if (winnerDeclared || squareAlreadyFilled) return;

    newSquares[i] = xIsNext ? 'X' : 'O';
    const newStep = { squares: newSquares };
    const newHistory = [...slicedHistory, newStep];

    setHistory(newHistory);
    setXIsNext(!xIsNext);
    setStepNumber(slicedHistory.length);
  };

  const moves = history.map((step, move) => {
    const description = Boolean(move)
      ? `Go to move #${move}`
      : `Go to game start`;
    return (
      <li key={move}>
        <button onClick={() => jumpTo(move)}>{description}</button>
      </li>
    );
  });

  const jumpTo = step => {
    setStepNumber(step);
    const isEvenStepNumber = step % 2 === 0;
    setXIsNext(isEvenStepNumber);
  };

  const currentStep = history[stepNumber];
  const winner = calculateWinner(currentStep.squares);

  const status = winner
    ? `Winner: ${winner}`
    : `Next player: ${xIsNext ? 'X' : 'O'}`;
  return (
    <div className="game">
      <div className="game-board">
        <Board
          squares={currentStep.squares}
          onClick={i => handleClick(i)}
        />
      </div>
      <div className="game-info">
        <div>{status}</div>
        <ol>{moves}</ol>
      </div>
    </div>
  );
};

// ========================================

ReactDOM.render(
  <Game />,
  document.getElementById('root')
);

/**
* calculateWinner (helper function)
*
* Parameter: squares (array of 'X', '0', or null)
* Return value: 'X', 'O', or null
*/
function calculateWinner(squares) {
  /* Squares indexes
  0 1 2
  3 4 5
  6 7 8
  */
  const lines = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6],
  ]; // mostra todas as combinações vencedoras ("linhas")
  // itera em todas as combinações de linhas vencedoras para ver se o array de quadrados de entrada
  // se tem uma com todos 'X's ou todos ' O's. Se verdadeiro, retorna 'X' ou 'O' dependendo de quem ganhou.
  for (let line of lines) {
    const [a, b, c] = line;
    if (
      squares[a] &&
      squares[a] === squares[b] &&
      squares[a] === squares[c]
    ) {
      return squares[a];
    }
  }
  // se nenhuma das combinações de linhas vencedoras estiver contida no array de quadrados de entrada
  // returna null...
  return null;
}

Ficamos por aqui por hora. 😉

Aula 06                        Aula 08

Todas as aulas desse curso

Voltar para página principal do blog

Código da aula:

https://github.com/toticavalcanti/tutorial-react/tree/tic_tac_toe_with_hooks

Se gostarem do conteúdo dêem um joinha 👍 na página do Código Fluente no
Facebook

Link do código fluente no Pinterest

Novamente deixo meus link de afiliados:

Hostinger

Digital Ocean

One.com

Obrigado, até a próxima e bons estudos. 😉

About The Author
-

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>