Ejercicio Partidas Rol

Vamos a crear un MVC para mantener una base de datos de partidas de rol y también una web API Rest y un frontend de React que hagan lo mismo.

La base de datos será así:

Jugador: Nombre, mail y alias
Partida: Nombre, juego, fecha y hora, dificultad

Todas las partidas tienen 1 creador.
Los jugadores pueden participar en varias partidas y una partida se compone de varios jugadores.

Tendremos que hacer:

1.- MVC con Code First (recordad en scaffolding)
2.- Web API Rest
3.- Probar API con Postman
4.- Diseñar el frontend, pantallas que tendrá, como se realizarán las acciones
5.- Construir el frontend en React: Crear las rutas, los componentes, hacer las llamadas a la api…

Enrutamiento

Instalar:

npm install react-router-dom

https://reacttraining.com/react-router/web/example/basic
https://learnwithparam.com/blog/basic-routing-in-react-router/
https://medium.com/@simonhoyos/enrutando-en-react-cd9e4ad6e3d3

Ejemplo:

import React from "react";
import {
BrowserRouter as Router,
        Switch,
        Route,
        Link,
        useParams,
        Redirect
        } from "react-router-dom";

export default function App() {
    return (
            <Router>
                <div>
                    <nav>
                        <ul>
                            <li>
                                <Link to="/">Home</Link>
                            </li>
                            <li>
                                <Link to="/about">About</Link>
                            </li>
                               <li>
                                <Link to="/acerca">Acerca</Link>
                            </li>
                            <li>
                                <Link to="/users">Users</Link>
                            </li>
                            <li>
                                <Link to="/usuario/1">us1</Link>
                            </li>
                            <li>
                                <Link to="/usuario/2">us2</Link>
                            </li>
                        </ul>
                    </nav>
            
            
                    <Switch>
                    <Route path="/usuario/:id"  component={Usuario} />
                       
                    <Route exact path="/about">
                        <About />
                    </Route>
                    <Route exact path="/acerca">
                        <Acerca />
                    </Route>
                    <Route path="/users" component={Users}/>
                    <Route exact path="/">
                        <Home />
                    </Route>
            
                    </Switch>
                </div>
            </Router>
            );
}

function Home() {
    return <h2>Home</h2>;
}

function About() {
    return <h2>About</h2>;
}
function Acerca() {
    return <Redirect to='/about' />;
}
function Users() {
    return <h2>Users</h2>;
}

function Usuario() {
    
    let {id} = useParams();

    return (
            <div>
                <h3>ID: {id}</h3>
            </div>
            );
}

JSX React

Fragmentos:

// Example 1: Using empty tags <></> 
  render() {
    return ( 
      <>
        <ComponentA />
        <ComponentB />
        <ComponentC />
      </>
    );
  }

// Example 2: Using React.Fragment 
  render() {
    return ( 
      <React.Fragment>
        <h1>An h1 heading</h1> 
        Some text here. 
        <h2>An h2 heading</h2> 
        More text here.
        Even more text here.
       </React.Fragment>
    ); 
  }

  // Example 3: Importing the Fragment
  import React, { Fragment } from 'react';

  render() {
    return ( 
      <Fragment>
        <h1>An h1 heading</h1> 
        Some text here. 
        <h2>An h2 heading</h2> 
        More text here.
        Even more text here.
      </Fragment>
    ); 
  }

  return [
      <li key="1">First item</li>, 
      <li key="2">Second item</li>, 
      <li key="3">Third item</li>
    ]; 
  }

Espacios:

 <div> 
    <span>My</span> 
    {' '}
    name is
    {' '} 
    <span>Carlos</span> 
  </div>

Spread atributes:

  const attrs = { 
    id: 'myId',
    className: 'myClass'
  };
   
  return <div {...attrs} />;

Esto nos sirve para pasar un estado como propiedades a otro componente:

class MyApp extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      name: 'CamperBot',
      price:0
    }
  }
  render() {
    return (
       <div>
         <Navbar {...this.state} />
       </div>
    );
  }
};

class Navbar extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
    <div>
      <h1>Hello, my name is: {this.props.name} {this.props.price} </h1>
    </div>
    );
  }
};

Condicionales:

<div> 
    {isLoggedIn && <LoginButton />} 
  </div>

  <div> 
    {isLoggedIn ? <LogoutButton /> : <LoginButton />} 
  </div>

Propiedades por defecto:

class Button extends React.Component { 
    render() { 
      return <button>{this.props.text}</button>;
    } 
  } 
   
  Button.propTypes = { 
    text: React.PropTypes.string
  };
   
  Button.defaultProps = { 
    text: 'Click me!'
  };

Tres maneras de hacer el binding de las funciones:

 class Button extends React.Component { 
    constructor(props) { 
      super(props);
   
      this.handleClick = this.handleClick.bind(this);
    } 
   
    handleClick() { 
      console.log(this);
    } 
   
    render() { 
      return <button onClick={this.handleClick} />;
    } 
  }

  class Button extends React.Component { 
    handleClick() { 
      console.log(this);
    } 
   
    render() { 
      return <button onClick={() => this.handleClick()} />;
    } 
  }

class Button extends React.Component {    
    handleClick = () => { 
      console.log(this);
    } 
   
    render() { 
      return <button onClick={this.handleClick} />;
    } 
  }

Cambiar estado:

// Incorrecto
this.setState({
  counter: this.state.counter + this.props.increment,
});

// Correcto
this.setState((state, props) => ({
  counter: state.counter + props.increment
}));