Enlaces React-Redux

Ejemplo de Crud en castellano (es traducción de otro artículo):

https://www.ma-no.org/es/programacion/javascript/ejemplo-completo-de-crud-con-redux-y-react

Guía definitiva que incluye muchas cosas y está muy bien explicada:

React Redux Tutorial for Beginners: The Definitive Guide (2020)

Ejemplo de Redux con un enlace diferente entre el store y las props:

Redux example

Una aplicación sencilla con react y redux:

https://dev.to/creativetim_official/how-to-use-redux-in-reactjs-with-real-life-examples-4gog

Diferentes maneras de hacer dispatch de acciones en react-redux:

https://www.pluralsight.com/guides/different-ways-to-dispatch-actions-with-redux

Middlewares en react:

https://www.metaltoad.com/blog/overview-redux-middleware-react-applications

Tutorial completo React+Redux:

https://medium.appbase.io/part1-getting-started-with-react-and-nextjs-4f28a6a0c38e

Tutorial completo redux:

https://developer.okta.com/blog/2019/03/18/beginners-guide-to-redux

Consejos para mejorar rendimiento:

https://itnext.io/3-small-tips-for-better-redux-performance-in-a-react-app-9cde549df6af

Tutorial:

https://www.creative-tim.com/blog/tutorial/reactjs-redux-tutorials/

React-redux + hooks:

https://thoughtbot.com/blog/using-redux-with-react-hooks

Tutorial Redux:

https://www.tutorialspoint.com/redux/index.htm

React tutorial con redux:

https://www.javatpoint.com/react-redux-example

Introducción bien explicada de react+redux:

https://medium.com/javascript-in-plain-english/the-only-introduction-to-redux-and-react-redux-youll-ever-need-8ce5da9e53c6

Redux crud example:

https://www.techandstartup.com/tutorials/react-redux-crud-app

Crear un CRUD en 5 minutos:

Fullstack CRUD:

https://medium.com/swlh/fullstack-crud-application-using-fastify-react-redux-mongodb-part-1-9e8df39c6fff

Ejercicio entidad bancaria 2.0

Vamos a modificar el ejercicio anterior para añadir la siguiente funcionalidad:

En lugar de tener una variable donde se sumen las entradas y salidas tendremos sendos arrays de objetos donde guardaremos un objeto con la cantidad que hemos sacado y el momento en el que lo hemos hecho.

Al comprobar los límites de retirada o de ingreso lo haremos con respecto a las últimas 24 horas (para las pruebas podemos utilizar un intervalo menor)

En el tema de los ingresos que van a depósito pasadas esas 24 horas se añaden a la cuenta eliminándose de la lista.

Además de todo esto tendremos una lista con las 20 últimas operaciones que se mostrarán por pantalla.

Ejercicio React-Redux: Cuenta Bancaria

Vamos a hacer un ejercicio que simule una cuenta bancaria. Tendrá los siguientes elementos:

Saldo: 5.324,6 €

Cantidad: (input text)

Botones: |Hacer ingreso| |Sacar dinero|

El usuario puede poner una cantidad y si le da hacer ingreso se incrementa el saldo y si le da a sacar dinero se resta.

Con las siguientes condiciones:

Si el ingreso es mayor de 1000 € se suman solo 1000 € y el resto estará pendiente de ingreso (y lo mostraremos en el saldo al lado en color verde)

Si intentamos sacar más dinero del que hay en la cuenta se mostrará ‘Saldo insuficiente’.

Si sacamos dinero la cantidad se queda guardada y si queremos sacar más de 1000 € en una o varias operaciones nos saldrá un mensaje ‘Límite superado’

Tutoriales react y redux

Conceptos de Redux (puros)

https://code.tutsplus.com/es/tutorials/getting-started-with-redux-why-redux–cms-30349

Ejemplo de app de contactos (incompleta):

https://code.tutsplus.com/es/tutorials/getting-started-with-redux-learn-by-example–cms-30350

Un ejemplo extenso:

https://www.valentinog.com/blog/redux/

Otro tutorial sencillo:

https://daveceddia.com/redux-tutorial/

Página oficial:

https://react-redux.js.org/introduction/quick-start

Crear proyecto con React y Redux

npx create-react-app redux-counter

cd redux-counter

npm install –save redux react-redux

Creamos Counter.js:

import React from 'react';

class Counter extends React.Component {
  state = { count: 0 }

  increment = () => {
    this.setState({
      count: this.state.count + 1
    });
  }

  decrement = () => {
    this.setState({
      count: this.state.count - 1
    });
  }

  render() {
    return (
      <div>
        <h2>Counter</h2>
        <div>
          <button onClick={this.decrement}>-</button>
          <span>{this.state.count}</span>
          <button onClick={this.increment}>+</button>
        </div>
      </div>
    )
  }
}

export default Counter;

Después de modificarlo:

import React from 'react';
import { connect } from 'react-redux';

function mapStateToProps(state) {
  return {
    count: state.count
  };
}

    
class Counter extends React.Component {
  //state = { count: 0 }

  increment = () => {
   this.props.dispatch({ type: "INCREMENT" });
  }

  decrement = () => {
  this.props.dispatch({ type: "DECREMENT" });
  }

  render() {
    return (
      <div>
        <h2>Counter</h2>
        <div>
          <button onClick={this.decrement}>-</button>
          <span>{this.props.count}</span>
          <button onClick={this.increment}>+</button>
        </div>
      </div>
    )
  }
}

export default connect(mapStateToProps)(Counter);

App

import React from 'react';
import logo from './logo.svg';
import './App.css';
import Counter from './Counter';
import { createStore } from 'redux';
import { Provider } from 'react-redux';

const initialState = {
  count: 0
};
function reducer(state = initialState, action) {
  console.log('reducer', state, action);
  switch (action.type) {
    case 'INCREMENT':
      return {
        count: state.count + 1
      };
    case 'DECREMENT':
      return {
        count: state.count - 1
      };
    case 'RESET':
      return {
        count: 0
      };
    default:
      return state;
  }
}
const store = createStore(reducer);

function App() {
  return (
    <Provider store={store}>
      <Counter />
    </Provider>
  );
}

export default App;

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
}));