Tutorial ReactJS 21-22

De wikijoan
Salta a la navegació Salta a la cerca

Introducció

Nota: versió antiga d'aquest tutorial (curs 19-20): (el codi del tutorial és exactament el mateix).

Dues opcions per a seguir el tutorial oficial de ReactJS:

1) learn by doing (aquest és el que seguim):

2) aprendre els conceptes:

Tutorial tic-tac-toe

Tic-tac-toe 2122.png

Instal·lació

Resultat final:

Setup Option 2: Local Development Environment

$ npx create-react-app my-app

Hem de tenir instal·lada la versió més recent de create-react-app

The latest instructions for creating a new app can be found here:

Per instal·lar la versió més recet de create-react-app:

$ npm i create-react-app

I ara ja podem crear el projecte:

$ npx create-react-app my-app

Fixar-se que s'ha creat el fitxer package.json

Delete all files in the src/ folder of the new project

cd my-app
cd src

# If you're using a Mac or Linux:
rm -f *

# Or, if you're on Windows:
del *

# Then, switch back to the project folder
cd ..

4. Add a file named index.css in the src/ folder with this CSS code (codi que indica el tutorial).

5. Add a file named index.js in the src/ folder with this JS code (codi que indica el tutorial).

6. Add these three lines to the top of index.js in the src/ folder:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';

I ara ja podem arrencar l'aplicació:

$ npm start

ja tenim l'aplicació, que encara no far res, però ja podem veure el taulell del 3 en ratlla.

Ara que ja hem fet la primera aplicació, és el moment de parlar de què és React.

Overview

What Is React?

El component principal és React.Component.

A component takes in parameters, called props (short for properties), and returns a hierarchy of views to display via the render method.

Nosaltres utilitzarem la sintaxi anomenada JSX.

De moment en el nostre projecte tenim 3 components de React: Square, Board i Game.

Per veure com podem passar dades a través de les props, fem els petits canvis a la classe Board i a la classe Square:

class Board extends React.Component {
  renderSquare(i) {
    return <Square value={i} />;
  }
}
class Square extends React.Component {
  render() {
    return (
      <button className="square">
        {this.props.value}
      </button>
    );
  }
}

i ara si mirem com es renderitza l'aplicatiu veiem que ens apareixen els números de les caselles.

Ara podem afegir un petit event:

class Square extends React.Component {
 render() {
   return (
     <button className="square" onClick={() => console.log('click')}>
       {this.props.value}
     </button>
   );
 }
}

Seguint el tutorial, ara parlem dels state que ens permeten guardar informació associada al component. D'aquesta manera, ja podem guardar la informació dels botons que hem clicat, i quedaran marcats amb una X.

class Square extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: null,
    };
  }

  render() {
    return (
      <button
        className="square"
        onClick={() => this.setState({value: 'X'})}
      >
        {this.state.value}
      </button>
    );
  }
}

Completar el joc

Per completar el joc, hem d'alternar les X i les O i determinar quan s'acaba el joc i qui guanya.

Necessitem saber els valors de cada quadrat-botó, i necessitem una variable que estigui més amunt que Square (és a dir, Board) per tenir la visió global de tot el taulell. Per tant, el valor del state dels quadrats (que estan a nivell de Square), els hem de pujar cap amunt (lift).

Definirem una matriu en el component Board:

class Board extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      squares: Array(9).fill(null),
    };
  }

  renderSquare(i) {
    return <Square value={this.state.squares[i]} />;
  }

I ara el següent pas important és gestionar com fem el click dels botons. Tenim un onclick a nivell del component Square, però hem de pujar cap amunt el seu comportament i definir el onclick a nivell de Board, on definirem la funció handleClick(), que actualitzarà la matriu squares.

En el component Board tenim:

  handleClick(i) {
    const squares = this.state.squares.slice();
    squares[i] = 'X';
    this.setState({squares: squares});
  }

Since the Square components no longer maintain state, the Square components receive values from the Board component and inform the Board component when they’re clicked. In React terms, the Square components are now controlled components. The Board has full control over them.

Per crear una còpia de l'array squares utilitzem el mètode slice(). Aquest fet és important.

La classe Square, que fins ara era un component que venia heredat de React.Component, ara la convertirem en una function component, i això ho podem fer en un component senzill on només tenim uns props com a entrada i una renderització com a valor retornat.

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

I ara ja podem implementar la lògica del joc: fer torns entre els dos jugadors (després de la X ve la O. I saber quan s'acaba la partida i quin és el guanyador.

I ja podem jugar una partida.

Adding time travel

Com a millora, anem a implementar la possibilitat d'anar endarrere en el temps i poder modificar una jugada.

Podem crear un array history, que emmagatzemi els arrays square cada cop que es faci una jugada. Qui guardarà la informació del history. No pot ser el Board, que guarda l'estat actual de la partida, sinó que ha de ser el component superior (Game), que pot guardar l'historial de totes les jugades. Per tant, haurem de fer el lifting del state cap amunt.

I això implicarà canvis en el Board component.

Finalment hem de poder mostrar els moviments anteriors (utilitzarem el mètode map dels arrays), i fer-los clicables, per poder anar a una jugada passada.

Necessitarem les claus key per tal d'identificar de forma unívoca els elements de la llista HTML, que és una llista dinàmica on els elements es creen i es destrueixen.

Després d'implementar tots els canvis proposats, ja podem jugar al tic-tac-toe que es proposa en el tutorial.

Crear el production build: desplegament al VPS del Jaume Balmes

$ npm run build

> my-app@0.1.0 build
> react-scripts build

Creating an optimized production build...
Compiled successfully.

File sizes after gzip:

  46.6 kB  build/static/js/main.bc13e26f.js
  362 B    build/static/css/main.22941023.css

The project was built assuming it is hosted at /.
You can control this with the homepage field in your package.json.

The build folder is ready to be deployed.
You may serve it with a static server:

  npm install -g serve
  serve -s build

Find out more about deployment here:

  https://cra.link/deployment

S'ha creat la carpeta build en el directori arrel del projecte (és a dir, en el mateix nivell que src/). Dins de la carpeta build/ trobem el fitxer index.html, i dins la carpeta static/ trobem les carpetes 'css/ i js/.

Per tant, si disposem d'un servidor web (ja sigui local o en el núvol), podem desplegar el nostre tic-tac-toe.

NOTA: si no funciona (Linux, Mac), afegir en el package.json el camp:

  "homepage":"./",

i tornar a compilar. Ja funciona:

o bé millor desplegar el tic-tac-toe al teu espai al núvol:

$ cd /ruta_projecte/build
$ ssh nom_usuari@vps-89148e22.vps.ovh.net -f 'mkdir /home/nom_usuari/html/tic-tac-toe'
$ scp -r * nom_usuari@vps-89148e22.vps.ovh.net:/home/nom_usuari/html/tic-tac-toe

i ja tenim publicada l'aplicació:


creat per Joan Quintana Compte, abril 2022