Header Ads Widget

Responsive Advertisement

Ticker

6/recent/ticker-posts

React parte 4



Estructura bàsica
App.js
import './App.css';
import alextechlogo from './images/1.png';

function App() {
  return (
    <div className='App'>
      <div className='alextech-logo-contenedor'>
      <h2>CALCULADORA ALEXTECH</h2>
        <img src={alextechlogo} className='alextech-logo' alt='Logo alextech' />
      </div>
    </div>
  );
}
export default App;
App.css estilos generales
.App {
    width: 100%;
    height: 100vh;
    padding-top: 10px;
    background-color: #0C0E12;
    font-family: Lato , sans-serif;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
}
h2 {
    color: #fff;
}
.alextech-logo-contenedor{
    width: 100%;
    height: 50px;
    margin: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
}
.alextech-logo {
    height: 50px;
}
Contenedor principal
App.js
<div className='contenedor-calculadora'>

      </div>
App.css
.contenedor-calculadora{
    width: 400px;
    height: 600px;
    padding: 14px;
    background-color: #000000;
    border-radius: 20px;
    border: 5px solid white;
}
Estructura de la calculadora
App.js
<div className='contenedor-calculadora'>
        <div className='fila'></div>
        <div className='fila'></div>
        <div className='fila'></div>
        <div className='fila'></div>
        <div className='fila'></div>
      </div>
App.css
Creaciones de las filas para la calculadora
.fila{
    margin: 4px;
    display: flex;
    align-items: center;
    justify-content: center;
}
Crear los componentes
{porps.children} hijos , todo lo que se encuentre entre las etiqueta de apertura y de cierre de Boton se va a considerar como children y podemos usarlo en nuestro componente , se reemplaza el valor en el componente 1 , ir a la consola de react components para verificar children.
-Creamos el componentes boton
Boton.js
import react from "react";

function Boton(props){
    return (
        <div>
            {props.children}
        </div>
    )
}
export default Boton;
exportamos e importamos a App.js
import './App.css';
import alextechlogo from './images/1.png';
//Importamos el componente Boton//
import Boton from './componenets/Boton';

function App() {
  return (
    <div className='App'>
      <div className='alextech-logo-contenedor'>
      <h2>CALCULADORA ALEXTECH</h2>
        <img src={alextechlogo} className='alextech-logo' alt='Logo alextech' />
      </div>
   
      <div className='contenedor-calculadora'>
        <div className='fila'>
//Componente boton creao con llave de apertura y cierre , children reemplaza//
          <Boton>1</Boton>
        </div>
        <div className='fila'></div>
        <div className='fila'></div>
        <div className='fila'></div>
        <div className='fila'></div>
      </div>
    </div>
  );
}

export default App;
Atributos de boton
Á ese boton le creamos la clase y la accion que va hacer el boton
-Comillas invertidas nos sirve para crearplantillas literales , nos permite crear una cadena de caracteres que puede contener cierto còdigo de javaascript para definir el resultado, queremos que todos los botones tengan ciertas propiedades css en comun , para ello definimos una clase mas general
-Nos sirve para crer clases mucho màs complejas , para insertar javascript utilizamos ${} , primero determina si es operador o no , la funcion se llama esOperador toma el valor de porps.children , dependiendode ese valor le asiganmos la clase , en resumen si es verdadero 
-Definimos una funcion esOperador(props.children) toma su valor dependiendo de ese valor le asignamos la clase ? 'operador ' : 'null'
Boton.js
function Boton(props){
    return (
        <div
            className={`boton-contenedor ${esOperador(props.children) ? 'operador' : null}`}>
            {props.children}
        </div>
    )
}
Definir una funcion
-valor nombre del parametro
-si se cumple estas 3condiones no es valor ,punto o igual ,entonces le consideramos como operador esOperador y retornamos verdadero true , caso contrario si es falso a de los criterios retorna falso
Boton.js
  const esOperador = valor =>{
        return isNaN(valor) && (valor != '.') && (valor != '=');
    };

Probar el boton 
.trim() nos pemrite remover espacios , trimEnd remueve al finarreturn (
        <div
            className={`boton-contenedor ${esOperador(props.children) ? 'operador' : ''}`.trimEnd()}>
            {props.children}
        </div>
    )
Estilo a botones
El texto no se pueda seleccionar con el raton
  user-select: none;
-Crer una carpeta hoja-de-estilos y un archivo Boton.css
.boton-contenedor {
  height: 83px;
  display: flex;
  flex: 1 1;
  justify-content: center;
  align-items: center;
  font-weight: bold;
  font-size: 38px;
  background-color: #7b827b;
  color: white;
  border-radius: 25px;
  border: 2px solid white;
  margin: 4px;
  cursor: pointer;
  user-select: none;
}
.operador {
  background-color: #FF262E;
}
Crear los botones
App.js
<div className='fila'>
          <Boton>1</Boton>
          <Boton>2</Boton>
          <Boton>3</Boton>
          <Boton>+</Boton>
        </div>
        <div className='fila'>
          <Boton>4</Boton>
          <Boton>5</Boton>
          <Boton>6</Boton>
          <Boton>-</Boton>
        </div>
        <div className='fila'>
          <Boton>7</Boton>
          <Boton>8</Boton>
          <Boton>9</Boton>
          <Boton>*</Boton>
        </div>
        <div className='fila'>
          <Boton>=</Boton>
          <Boton>0</Boton>
          <Boton>.</Boton>
          <Boton>/</Boton>
        </div>
        <div className='fila'></div>
Estilos para botones
Botones.css
.boton-contenedor {
  height: 83px;
  display: flex;
  flex: 1 1;
  justify-content: center;
  align-items: center;
  font-weight: bold;
  font-size: 38px;
  background-color: #7b827b;
  color: white;
  border-radius: 25px;
  border: 2px solid white;
  margin: 4px;
  cursor: pointer;
  user-select: none;
}
.boton-contenedor:hover{
background-color: #131313;
}

.operador {
  background-color: #FF262E;
}
.operador:hover {
  background-color: #b40608;
}
Componente pantalla
Crear un nuevo componente  Pantalla.js .vamos a retornar la esctructura del componente , esta isntaxis es para componentes mas sencillos que tengan i+una presentacion , no para logicos o funciones.
   /* LLaves reemplazamos codigo de js */
    {input}
Definir un componente con una funcion flecha
Le asignmaos como constante para que no se pueda reasignar
Pantalla.js
import React from 'react';

const Pantalla = ({input}) => (
  <div className='input'>
//Remmeplazamos el valor del prop//
    {input}
  </div>
);
Export default Pantalla;
Retornamos ese valor =>
App.js
Agregamos componente Pantalla
  <div className='contenedor-calculadora'>
        <Pantalla/>
        <div className='fila'>
          <Boton>1</Boton>
          <Boton>2</Boton>
          <Boton>3</Boton>
          <Boton>+</Boton>
Estilo para pantalla
Se alinea a la derecha horizontal
 justify-content: flex-end;
Alinear en en centro verticalmente
    align-items: center;
Pantalla.css
.input{
    height: 75px;
    border-radius: 30px;
    margin-bottom: 20px;
    display: flex;
    justify-content: flex-end;
    align-items: center;
    font-weight: bold;
    font-size: 30px;
    background-color:#131313;
    color: white;
    padding: 11px 30px 11px 11px;
    margin: 1px solid #888;
    box-shadow: -1px 2px 3px 1px white;
   
}
Pantalla.js
Importamos los estilos
import React from 'react';
import '../hojas-de-estilo/Pantalla.css';
Bton clear
-Crear el componente boton BotonClera.js
-Pudiese estar esta alternativa Clear directamente y no 
const BotonClear =(props) => (
    <div className='boton-clear'>
       Clear
    </div>
y no Clear es fijo no va a cambiar
const BotonClear =(props) => (
    <div className='boton-clear'>
        {props.children}
    </div>
Si el valor de children no va cambiar ,cuando se cree distintas instancias del mismo componente se escribe directamente en el componenete
BotonClear.js
import React from 'react';

const BotonClear =(props) => (
    <div className='boton-clear'>
        {props.children}
    </div>
);
export default BotonClear;
Importamos BtonClear App.js
import Pantalla from './componenets/Pantalla';
import BotonClear from './componenets/BotonClear';
App.js
  <div className='fila'>
          <BotonClear>Clear</BotonClear>
Estilo para BotonClear
BotonClear.css
.boton-clear{
height: 80px;
font-size: 1.6em;
display: flex;
flex: 1;
background-color:#b40608 ;
margin-top: 8px;
justify-content: center;
align-items: center;
font-weight: bold;
color: white;
border: 2px solid white;
cursor: pointer;
border-radius: 30px;
}
.boton-clear:hover {
background-color:#FF262E ;
}
BotonClear.js importamos el componente
import React from 'react';
import '../hojas-de-estilo/BotonClear.css';
Imprementar la lògica de la calculadora
Mostar input en la pantalla
 . lo que significa que podemos agregarle un estado a nuestro componente.
-Usaremos un estado para la App llamado Input y tenemos una funcion para actualizar el imput setInput, ese input va a ser una cadena vacia
import { useState } from 'react';

function App() {
  const [input ,setInput] = useState('');

-En en componente pantalla vamos a pasar el prop input con el valor del estado input
 <div className='contenedor-calculadora'>
        <Pantalla input={input}/>
        <div className='fila'>
          <Boton>1</Boton>
          <Boton>2</Boton>
          <Boton>3</Boton>
          <Boton>+</Boton>
Recordemos que en Pantalla.js recibe una propiedad input ({input})
-2 funciones ,concatena
function App() {
  const [input ,setInput] = useState('');
 
  const agregarInput = val => {
    setInput(input + val);
  };
Asignar eventListener
En boton js esta tomando el paremetro props
function Boton(props){

    const esOperador = valor =>{
        return isNaN(valor) && (valor != '.') && (valor != '=');
    };
Le pasamos un prop manejar clic
App.js agregamos acada uno manejarClic={agregarInput}
      <div className='contenedor-calculadora'>
        <Pantalla input={input}/>
        <div className='fila'>
          <Boton manejarClic={agregarInput}>1</Boton>
          <Boton manejarClic={agregarInput}>2</Boton>
          <Boton manejarClic={agregarInput}>3</Boton>
          <Boton manejarClic={agregarInput}>+</Boton>
        </div>
        <div className='fila'>
          <Boton manejarClic={agregarInput}>4</Boton>
          <Boton manejarClic={agregarInput}>5</Boton>
          <Boton manejarClic={agregarInput}>6</Boton>
          <Boton manejarClic={agregarInput}>-</Boton>
        </div>
        <div className='fila'>
          <Boton manejarClic={agregarInput}>7</Boton>
          <Boton manejarClic={agregarInput}>8</Boton>
          <Boton manejarClic={agregarInput}>9</Boton>
          <Boton manejarClic={agregarInput}>*</Boton>
        </div>
        <div className='fila'>
          <Boton manejarClic={agregarInput}>=</Boton>
          <Boton manejarClic={agregarInput}>0</Boton>
          <Boton manejarClic={agregarInput}>.</Boton>
          <Boton manejarClic={agregarInput}>/</Boton>
        </div>
        <div className='fila'>
          <BotonClear>Clear</BotonClear>
        </div>
Boton.js

 return (
        <div
            className={`boton-contenedor ${esOperador(props.children) ? 'operador' : ''}`.trimEnd()}>
            onClick={props.manejarClic(props.children)}>
//props.childrenlo pasamos como un argumento//
            {props.children}
        </div>
    )
}
-Nuestra pantalla se queda en blanco por errores , onclick  se esperaba que retorne una funcion , creamos una funcion flecha
Corregimos cuando un click llamara a una funcion
-Definimos una funcion anonima que se retornara una vez ,es una funcion nueva , no toma ningun parametro , llamando a la funcion
onClick={() => props.manejarClic(props.children)}>
-Es una llamada a la funcion que se iba a ejecutar de esta manera escrita
onClick={props.manejarClic(props.children)}>

Boton.js ,problemas con > en la liena className tener en cuenta borrar , con eso ya podemos escribir los numeros en la pantalla

    return (
        <div
            className={`boton-contenedor ${esOperador(props.children) ? 'operador' : ''}`.trimEnd()}
            onClick={() => props.manejarClic(props.children)} // me dio problemas//>
            {props.children}
        </div>
    );
EventListener para en BotonClear
App.js definimos la funcion de esta manera y pasamos con el valor del prop
  const agregarInput = val => {
    setInput(input + val);
  };
Valor del props
<Boton manejarClic={agregarInput}>1</Boton>
          <Boton manejarClic={agregarInput}>2</Boton>
          <Boton manejarClic={agregarInput}>3</Boton>
          <Boton manejarClic={agregarInput}>+</Boton>
App.js
    <div className='fila'>
          <BotonClear manejarClear={() => setInput('')}>Clear</BotonClear>
        </div>
BotonClear.js
const BotonClear =(props) => (
    <div className='boton-clear' onClick={props.manejarClear}>
        {props.children}
    </div>
);
Calcular el resultado
App.js
  //Calcular resultado//
  const calcularResultado = () => {
    setInput(evaluate(input));
  };
  //------------------//
Conseguimos en un paquete math.js
import { useState } from 'react';
import { evaluate } from 'mathjs';
npm install mathjs debemos instalarlo por paquete npm
App.js
<div className='fila'>
          <Boton manejarClic={calcularResultado}>=</Boton> //calcular resultado
          <Boton manejarClic={agregarInput}>0</Boton>
          <Boton manejarClic={agregarInput}>.</Boton>
          <Boton manejarClic={agregarInput}>/</Boton>
        </div>
Manejar input vacio
-Nos retorna el error de undifined8 , evalua una expresion que no existe
-Valores truthy o falsy valores que por si solos son verdades o falsos , vacias son falsas y si no estan vacias son verdaderas
-Despues de las funciones flechas es recomendable incluir punto y coma.
Recomendaciones finales y correciones
Boton-js
    const esOperador = valor =>{
        return isNaN(valor) && (valor !== '.') && (valor !== '=');
    };
Que la comparacion sea estricta
en Boton.js
  return (
        <div
            className={`boton-contenedor ${esOperador(props.children) ? 'operador' : ''}`.trimEnd()}
            onClick={() => props.manejarClic(props.children)}>
            {props.children}
        </div>
    );
}
Realizamos unos cambios

freeCodeCamp Español. (2022, March 15). Aprende React Desde Cero - Curso de React Con Proyectos [Video]. YouTube. https://www.youtube.com/watch?v=6Jfk8ic3KVk