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