zamarrowski / curso-react-testing-graphql Goto Github PK
View Code? Open in Web Editor NEWCurso React, testing y GraphQL
Curso React, testing y GraphQL
import { changeOrderByPrice, getPriceColor } from './Functions'
test('order ascending', () => {
const productsOreder = [
{
id: 1,
name: 'Chachopo',
price: 30,
},
{
id: 3,
name: 'Navajas',
price: 25,
},
{
id: 2,
name: 'Chorizo a la sidra',
price: 15,
}
]
const products = [
{
id: 3,
name: 'Navajas',
price: 25,
},
{
id: 1,
name: 'Chachopo',
price: 30,
},
{
id: 2,
name: 'Chorizo a la sidra',
price: 15,
}
]
expect(changeOrderByPrice(products)).toStrictEqual(productsOreder);
expect(changeOrderByPrice()).toBe(null);
})
test('color red', () => {
expect(getPriceColor(30)).toBe('red');
})
test('color orange', () => {
expect(getPriceColor(25)).toBe('orange');
})
test('color green', () => {
expect(getPriceColor()).toBe('green');
expect(getPriceColor(undefined)).toBe('green');
expect(getPriceColor(null)).toBe('green');
expect(getPriceColor(15)).toBe('green');
})
import React, {useState, useEffect} from 'react'
function CallApi(props) {
const [data, setData] = useState([])
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/todos')
.then(response => response.json())
.then(posts => setData(posts))
}, [])
return (
<ul>
{data.map((item) => (
<li key={item.id}>{item.title}</li>
))}
</ul>
)
}
export default CallApi
app.js
import React from 'react'
import './App.css'
import Product from './Product'
class App extends React.Component {
state = {
selectedProducts: [],
promoText: '',
applyDiscount: false,
}
products = [
{
descriptionImg: 'iphone x',
img: 'https://store.storeimages.cdn-apple.com/4668/as-images.apple.com/is/refurb-iphoneX-spacegray_AV2?wid=1144&hei=1144&fmt=jpeg&qlt=80&op_usm=0.5,0.5&.v=1548459944179',
name: 'iPhone X',
price: 1000
},
{
descriptionImg: 'iphone 8',
img: 'https://store.storeimages.cdn-apple.com/4668/as-images.apple.com/is/refurb-iphone8-gold?wid=1144&hei=1144&fmt=jpeg&qlt=80&op_usm=0.5,0.5&.v=1542226468997',
name: 'iPhone 8',
price: 800
},
{
descriptionImg: 'iphone 7',
img: 'https://images-na.ssl-images-amazon.com/images/I/618wAPmPJPL._AC_SL1000_.jpg',
name: 'iPhone 7',
price: 700
}
]
componentDidMount() {
if (localStorage.products) {
this.setState({
selectedProducts: JSON.parse(localStorage.products)
})
}
}
addProduct = product => {
this.setState({
selectedProducts: [...this.state.selectedProducts, {...product, id: Math.random()}]
}, () => {
localStorage.products = JSON.stringify(this.state.selectedProducts)
})
}
removeProduct = product => {
this.setState({
selectedProducts: this.state.selectedProducts.filter(p => p.id !== product.id)
}, () => {
localStorage.products = JSON.stringify(this.state.selectedProducts)
})
}
getTotalPrice = () => {
let total = this.state.selectedProducts.reduce((prev, next) => prev + next.price, 0)
if (this.state.applyDiscount) return total * 0.9
return total
}
handleChange = e => {
this.setState({
promoText: e.target.value
})
}
applyDiscount = () => {
if (this.state.promoText === 'SAVE10') {
this.setState({
applyDiscount: true
})
} else {
alert('Código incorrecto')
}
}
render() {
return (
<div className="app-container">
<div>
<h1>Products</h1>
<div className="products-container">
{this.products.map(product => (
<Product
key={product.name}
descriptionImg={product.descriptionImg}
img={product.img}
name={product.name}
price={product.price}
onAddProduct={() => this.addProduct(product)}
/>
))}
</div>
</div>
<div className="cart-container">
<h1>Cart</h1>
{this.state.selectedProducts.length === 0 && <p>No products added</p>}
<div className="products-container">
{this.state.selectedProducts.map(product => (
<Product
key={product.name}
descriptionImg={product.descriptionImg}
img={product.img}
name={product.name}
price={product.price}
onRemoveProduct={() => this.removeProduct(product)}
/>
))}
</div>
<p>Total price: {this.getTotalPrice()}€</p>
<input placeholder="PROMO CODE" type="text" onChange={this.handleChange} />
<button onClick={this.applyDiscount}>Apply</button>
</div>
</div>
)
}
}
export default App
Product.js
import React from 'react'
export default props =>
<div>
<img alt={props.descriptionImg} src={props.img} height="150px" />
<p>{props.name}</p>
<p>{props.price}€</p>
{props.onAddProduct && (
<button onClick={props.onAddProduct}>Añadir</button>
)}
{props.onRemoveProduct && (
<button onClick={props.onRemoveProduct}>Borrar</button>
)}
</div>
FormTest.js
import React from 'react'
import InputError from './InputError'
export default class FormTest extends React.Component {
render() {
return (
<>
<InputError />
</>
)
}
}
helpers.js
export const sum = (num1, num2) => num1 + num2
InputError.js
import React from 'react'
const validText = 'A tope con React'
export default class InputError extends React.Component {
state = {
text: ''
}
render() {
return(
<>
<input
type="text"
value={this.state.text}
onChange={e => this.setState({ text: e.target.value })}
/>
{this.state.text !== validText && <p style={{color: 'red'}}>El texto introducido no mola</p>}
</>
)
}
}
Login.js
import React from 'react'
export default class Login extends React.Component {
state = {
username: '',
password: '',
}
handleChange = e => {
this.setState({
[e.target.name]: e.target.value
})
}
checkForm = () => {
return this.state.username && this.state.password.length >= 8
}
onSubmitForm = e => {
console.log(this.state)
e.preventDefault()
}
render() {
return (
<form onSubmit={this.onSubmitForm} onChange={this.handleChange}>
<input name="username" type="text" />
<input name="password" type="password" />
<button disabled={!this.checkForm()} type="submit">Login</button>
</form>
)
}
}
Select.js
import React from 'react'
export default props =>
<select value={props.value} onChange={props.onChange}>
{props.items.map(val => (
<option value={val}>{val}</option>
))}
</select>
select.test.js
import { sum } from './helpers'
test('Should return 4', () => {
expect(sum(2, 2)).toBe(4)
})
<li><input type="text" value={props.item.val} onChange={(e) => props.onChange(e,props.item.id) } /><Boton label="borrar" onClick={() => props.eliminarItem(props.item.id)} /></li>
en onChange ¿cuando se añade la función con un arrow function y cuando no hace falta?
import React from 'react'
class Tasks extends React.Component {
state = {
tasks: []
}
componentDidMount() {
this.fetchTasks()
}
fetchTasks = async () => {
let response = await (await fetch('https://jsonplaceholder.typicode.com/todos')).json()
this.setState({ tasks: response })
}
render() {
return <pre>{JSON.stringify(this.state.tasks)}</pre>
}
}
export default Tasks
import ShowDate from "../1-render/ShowDate";
import React, {useState} from 'react'
import ReplaceLetter from './ReplaceLetter'
function Main() {
const [show, setShow] = useState(true)
return (
<>
<button onClick={() => setShow(!show)}>toggle replace</button>
{show && <ReplaceLetter />}
</>
)
}
export default Main
import React from 'react';
import { Link } from 'react-router-dom';
export default function Navbar() {
return (
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/users">Users</Link>
</li>
</ul>
</nav>
)
}
store/configureStore.js
import { createStore } from 'redux'
import rootReducer from './reducers'
export default function configureStore() {
return createStore(rootReducer, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__())
}
store/reducers.js
import { combineReducers } from 'redux'
import form from './../form.reducer'
export default combineReducers({
form
})
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import { Provider } from 'react-redux'
import configureStore from './store/configureStore'
let store = configureStore()
ReactDOM.render(<Provider store={store}><App /></Provider>, document.getElementById('root'));
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
form.actions.js
export const changeName = name => {
return {
type: 'CHANGE_NAME',
name
}
}
export const changeAge = age => {
return {
type: 'CHANGE_AGE',
age
}
}
form.reducer.js
const initialState = {
name: '',
age: 0
}
export default function(state=initialState, action) {
switch (action.type) {
case 'CHANGE_NAME':
return { ...state, name: action.name }
case 'CHANGE_AGE':
return { ...state, age: action.age }
default:
return state
}
}
app.js
import React from 'react';
import './App.css';
import { connect } from 'react-redux'
import * as formActions from './form.actions'
import UserInfo from './UserInfo';
function App(props) {
return (
<div className="App">
<input type="text"
value={props.name}
onChange={e => props.changeName(e.target.value)}
/>
<input type="number"
value={props.age}
onChange={e => props.changeAge(e.target.value)}
/>
<UserInfo />
</div>
);
}
const mapStateToProps = state => {
return {
name: state.form.name,
age: state.form.age,
}
}
const mapDispatchToProps = dispatch => {
return {
changeName: name => dispatch(formActions.changeName(name)),
changeAge: age => dispatch(formActions.changeAge(age)),
}
}
export default connect(mapStateToProps, mapDispatchToProps)(App);
Hola!
Estaba trabajando con el LocalStorage, y en una función de añadir item actualizo el state:
this.setState({cart: [...this.state.cart,{id:addProduct.id,units:1}]})
console.log(this.state.cart)
Pero curiosamente cuando imprimo a continuación el valor de state me devuelve el estado anterior, la solución parece ser esta:
let newCart = [...this.state.cart,{id:addProduct.id,units:1}]
this.setState({cart: newCart})
console.log(newCart)
Me gustaría saber a que se debe, gracias!
import React from 'react';
import logo from './logo.svg';
import './App.css';
import Select from './Select';
const languages = [
{
value: 'es',
text: 'español'
},
{
value: 'en',
text: 'english'
}
]
const countries = [
{
value: 'es',
text: 'spain'
},
{
value: 'usa',
text: 'usa'
}
]
class App extends React.Component {
state = {
selectedLanguage: 'es',
selectedCountry: 'es',
}
render() {
return (
<div className="App">
<header className="App-header">
<Select
items={languages}
value={this.state.selectedLanguage}
onChange={(e) => this.setState({ selectedLanguage: e.target.value })}
/>
<Select
items={countries}
value={this.state.selectedCountry}
onChange={(e) => this.setState({ selectedCountry: e.target.value })}
/>
</header>
</div>
);
}
}
export default App;
¡Hola!
Me gustaría saber si vamos a aprender el Server side rendering para que nuestras aplicaciones sean cacheables por google :) ya que por defecto react carga todo el contenido dinámicamente, y el código fuente muestra solo el div root, gracias!
import React from 'react'
import { getTotalPrice } from './clase3_3/helpers'
import Products from './clase3_3/Products'
import productsConstants from './clase3_3/products.constants'
class App extends React.Component {
state = {
products: [],
code: '',
applyDiscount: false,
}
componentDidMount() {
if (localStorage.fictiziaShop) this.setState(JSON.parse(localStorage.fictiziaShop))
}
componentDidUpdate() {
localStorage.fictiziaShop = JSON.stringify(this.state)
}
addProduct = product => {
this.setState({ products: [...this.state.products, product] })
}
removeProduct = product => {
this.setState({ products: this.state.products.filter(p => p.id !== product.id) })
}
handleChangeCode = e => {
this.setState({ code: e.target.value })
}
applyDiscount = () => {
if (this.state.code !== 'SAVE10') {
alert('codigo erroneo')
} else {
this.setState({ applyDiscount: this.state.code === 'SAVE10' })
}
}
render() {
return (
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr' }}>
<div>
<h1>Products</h1>
<Products
products={productsConstants}
onAddProduct={this.addProduct}
button={(product) => <button onClick={() => this.addProduct(product)}>Add</button>}
/>
</div>
<div>
<h1>Cart</h1>
<Products
products={this.state.products}
onAddProduct={this.addProduct}
button={(product) => <button onClick={() => this.removeProduct(product)}>Remove</button>}
/>
<h3>Total: {getTotalPrice(this.state.products, this.state.applyDiscount)}€</h3>
<input onChange={this.handleChangeCode} type="text" placeholder="CODE" />
<button onClick={this.applyDiscount}>Apply</button>
</div>
</div>
)
}
}
export default App
const Products = props => props.products.map(product => (
<div key={product.id}>
<img src={product.image} />
<p>{product.name}</p>
<p>{product.price}€</p>
{/* <button onClick={() => props.onAddProduct(product)}>Add</button> */}
{props.button(product)}
</div>
))
export default Products
helpers.js
export const getHobbies = (hobby, checked, hobbies) => {
if (checked) {
return [...hobbies, hobby]
} else {
return hobbies.filter(h => h !== hobby)
}
}
Form.js
import React from 'react'
import { getHobbies } from './helpers'
export default class Form extends React.Component {
state = {
name: '',
firstName: '',
description: '',
gender: '',
age: 0,
country: '',
province: '',
hobbies: []
}
handleChange = (e) => {
let name = e.target.name
let value = e.target.value
if (e.target.type === 'checkbox') {
value = getHobbies(e.target.value, e.target.checked, this.state.hobbies)
}
this.setState({
[name]: value
})
}
handleSubmit = e => {
console.log(this.state)
e.preventDefault()
}
render() {
return (
<form onChange={this.handleChange} onSubmit={this.handleSubmit}>
<input type="text" name="name" />
<input type="text" name="firstName" />
<textarea name="description" />
<input type="radio" name="gender" value="male" /> Male
<input type="radio" name="gender" value="female" /> Female
<input type="number" name="age" />
<select name="country">
<option>Select one</option>
<option value="spain">Spain</option>
<option value="usa">USA</option>
</select>
{this.state.country === 'spain' && (
<select name="province">
<option>Select one</option>
<option value="guadalajara">Guadalajara</option>
<option value="madrid">Madrid</option>
</select>
)}
<label>
<input name="hobbies" type="checkbox" value="Games" />
Games
</label>
<label>
<input name="hobbies" type="checkbox" value="Football" />
Football
</label>
<label>
<input name="hobbies" type="checkbox" value="Basketball" />
Basketball
</label>
<label>
<input name="hobbies" type="checkbox" value="Art" />
Art
</label>
<button type="submit">Enviar</button>
</form>
)
}
}
helpers.test.js
const { getHobbies } = require("./helpers")
test('Should remove football from array', () => {
expect(getHobbies('football', false, ['football']).length).toBe(0)
expect(getHobbies('football', false, ['football'])).not.toContain('football')
})
test('Should add football from array', () => {
expect(getHobbies('football', true, ['basketball']).length).toBe(2)
expect(getHobbies('football', true, ['basketball'])).toContain('football')
expect(getHobbies('football', true, ['basketball'])).toContain('basketball')
})
App.js
import React from 'react'
import './App.css'
import productsConstants from './products.constants'
import ProductsList from './ProductsList'
class App extends React.Component {
state = {
selectedProducts: [],
codeText: '',
applyDiscount: false,
}
addProduct = product => {
this.setState({ selectedProducts: [...this.state.selectedProducts, product] })
}
removeProduct = product => {
this.setState({ selectedProducts: this.state.selectedProducts.filter(p => p.id !== product.id) })
}
getTotalPrice = () => {
let totalPrice = this.state.selectedProducts.reduce((prev, next) => prev + next.price, 0)
if (this.state.applyDiscount) totalPrice *= 0.90
return totalPrice
}
applyDiscount = () => {
if (this.state.codeText === 'SAVE10') {
this.setState({ applyDiscount: true })
} else {
alert('Invalid code')
}
}
onHandleCode = e => {
this.setState({ codeText: e.target.value })
}
componentDidUpdate() {
localStorage.setItem('state', JSON.stringify(this.state))
}
componentDidMount() {
this.setState(JSON.parse(localStorage.getItem('state')))
}
render() {
return (
<div>
<div>
<h1>Products</h1>
<ProductsList products={productsConstants} onClick={this.addProduct} actionLabel="Add product" />
</div>
<div>
<h1>Selected products</h1>
<ProductsList products={this.state.selectedProducts} onClick={this.removeProduct} actionLabel="Remove product" />
<p>Total price: {this.getTotalPrice()}</p>
<input type="text" placeholder="Type code" onChange={this.onHandleCode} />
<button onClick={this.applyDiscount}>Apply discount</button>
</div>
</div>
)
}
}
export default App
ProductsList.js
import React from 'react'
const ProductsList = props =>
props.products.map(product => (
<div key={product.id}>
<div>Name: {product.name}</div>
<div>Price: {product.price}</div>
<img width="100" src={product.img} alt="" />
<button onClick={() => props.onClick(product)}>{props.actionLabel}</button>
</div>
))
export default ProductsList
products.constants.js
export default [
{
id: 1,
name: 'iPhone 11',
price: 700,
img: 'https://thumb.pccomponentes.com/w-530-530/articles/23/233093/n1.jpg'
},
{
id: 2,
name: 'iPhone 12',
price: 800,
img: 'https://thumb.pccomponentes.com/w-530-530/articles/23/233099/b1.jpg'
},
{
id: 3,
name: 'iPhone 12S',
price: 1000,
img: 'https://thumb.pccomponentes.com/w-530-530/articles/17/170988/iphone-xs-gold-58-2-g97c-uw.jpg'
}
]
import React from 'react';
import {
BrowserRouter as Router,
Switch,
Route,
} from "react-router-dom";
import {
Home,
Users,
UserDetail,
NotFound,
} from './RouterComponents';
import Navbar from './Navbar';
export default function RouterContent() {
return (
<Router>
<Navbar />
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route path="/users/:id">
<UserDetail />
</Route>
<Route path="/users">
<Users />
</Route>
<Route path="*">
<NotFound />
</Route>
</Switch>
</Router>
)
}
AddTaskButton.js
import React from 'react'
export default props => <button onClick={props.onAdd}>Add task</button>
InputText.js
import React from 'react'
export default props => <input type="text" value={props.value} onChange={props.onChange} />
List.js
import React from 'react'
import ListItem from './ListItem'
export default props =>
<ul>
{props.tasks.map(task => (
<ListItem
key={task.id}
task={task}
onRemove={props.onRemove}
onEdit={props.onEdit}
/>
))}
</ul>
ListContainer.js
import React from 'react'
import List from './List'
import InputText from './InputText'
import AddTaskButton from './AddTaskButton'
class ListContainer extends React.Component {
state = {
tasks: [{
id: 10001,
title: 'Comprar el pan'
}, {
id: 10002,
title: 'Sacar a India'
}],
newTaskText: ''
}
handleNewTaskText = e => {
this.setState({ newTaskText: e.target.value })
}
addTask = () => {
this.setState({
tasks: [...this.state.tasks, { id: Math.random(), title: this.state.newTaskText }],
newTaskText: '',
})
}
removeTask = taskId => {
let newTasks = this.state.tasks.filter(task => task.id !== taskId)
this.setState({ tasks: newTasks })
}
editTask = (taskId, value) => {
const newTasks = this.state.tasks.map(task => {
if (task.id === taskId) task.title = value
return task
})
this.setState({ tasks: newTasks })
}
render() {
return (
<>
<List tasks={this.state.tasks} onRemove={this.removeTask} onEdit={this.editTask} />
<InputText onChange={this.handleNewTaskText} value={this.state.newTaskText} />
<AddTaskButton onAdd={this.addTask} />
</>
)
}
}
export default ListContainer
ListItem.js
import React from 'react'
import RemoveTaskButton from './RemoveTaskButton'
export default props =>
<>
<li>
<input
type="text"
value={props.task.title}
onChange={e => props.onEdit(props.task.id, e.target.value)}
/>
</li>
<RemoveTaskButton onRemove={() => props.onRemove(props.task.id)} />
</>
RemoveTaskButton.js
import React from 'react'
export default props => <button onClick={props.onRemove}>Remove</button>
Seconds.js
import React from 'react'
export default class Seconds extends React.Component {
state = {
count: 0
}
componentDidMount() {
setInterval(() => {
this.setState(prevState => ({count: prevState.count++}))
}, 1000)
}
render() {
return (
<>
<h1>{this.state.count}</h1>
</>
)
}
}
Tasks.js
import React from 'react'
export default class Tasks extends React.Component {
state = {
tasks: []
}
fetchTasks = async () => {
let data = await (await fetch('https://jsonplaceholder.typicode.com/todos')).json()
this.setState({ tasks: data })
}
componentDidMount() {
this.fetchTasks()
}
render() {
return <pre>{JSON.stringify(this.state.tasks)}</pre>
}
}
Test.js
import React from 'react'
class Test extends React.Component {
state = {
text: 'hola',
}
componentDidMount() {
console.log('despues del primer render')
}
componentDidUpdate() {
console.log('se ha actualizado')
}
componentWillUnmount() {
console.log('adiós')
}
render() {
return (
<>
<h1>{this.state.text}</h1>
<input type="text" onChange={e => this.setState({ text: e.target.value })} />
</>
)
}
}
export default Test
Users.js
import React from 'react'
export default class Users extends React.Component {
state = {
users: ['sergio', 'vero']
}
componentDidMount() {
this.setState(prevState => ({ users: [...prevState.users, 'cris'] }))
}
render() {
return <p>{this.state.users.join(', ')}</p>
}
componentWillUnmount() {
console.log('¡Componente destruido!')
}
}
App.js
import React from 'react'
import './App.css'
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from 'react-router-dom'
import HomePage from './clase9/HomePage'
import UsersPage from './clase9/UsersPage'
import NotFoundPage from './clase9/NotFoundPage'
const App = () => {
return (
<div>
<Router>
<nav>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/users">Users</Link></li>
</ul>
</nav>
<Switch>
<Route exact path="/">
<HomePage />
</Route>
<Route path="/users">
<UsersPage />
</Route>
<Route path="*">
<NotFoundPage />
</Route>
</Switch>
</Router>
</div>
)
}
export default App
NotFoundPage.js
import React from 'react'
export default () => <h1>Page not found</h1>
UsersPage.js
import React from 'react'
import { Link, Switch, Route } from 'react-router-dom'
import UserDetail from './UserDetail'
const users = [{id: 1, username: 'zamarro'}, { id: 2, username: 'Cristina' }]
export default () => (
<>
<Switch>
<Route exact path="/users">
<ul>
{users.map(user => (
<li key={user.id}>
<Link to={`/users/${user.id}`}>{user.username}</Link>
</li>
))}
</ul>
</Route>
<Route path="/users/:id">
<UserDetail />
</Route>
</Switch>
</>
)
HomePage.js
import React from 'react'
export default () => <h1>¡Bienvenido!</h1>
UserDetail.js
import React from 'react'
import { useParams } from 'react-router-dom'
export default () => {
const { id } = useParams()
return (<h1>El user id es: {id}</h1>)
}
import React, { Component } from 'react'
const products = [
{
id: 1,
name: "Product1",
price: 200
},
{
id: 2,
name: "Product2",
price: 500
},{
id: 3,
name: "Product3",
price: 1200
}
];
export default class Shop extends Component {
state = {
selectedProducts: [],
couponName: '',
isCouponValid: false
}
componentDidMount() {
let selectedProducts = JSON.parse(localStorage.selectedProducts || '[]');
let isCouponValid = !!localStorage.isCouponValid;
this.setState({selectedProducts, isCouponValid});
}
render() {
return (
<div>
<div className="products">
{products.map(product =>
<div key={product.id} className="product">
<div className="productName">{product.name}</div>
<div className="productPrice">{product.price}</div>
<button onClick={() => this.addProduct(product)}>Añadir</button>
</div>
)}
</div>
<hr/>
<div className="cart">
Cart <span>Total {this.totalPrice()}$</span>
<ul className="cartProducts">
{this.state.selectedProducts.map((product, key) =>
<li key={key} className="product">
<div className="productName">{product.name}</div>
<div className="productPrice">{product.price}</div>
<button onClick={() => this.removeProduct(product)}>Borrar</button>
</li>
)}
</ul>
</div>
<div className="coupon">
<input value={this.state.couponName}
onChange={this.handleChange} type="text"/>
<button onClick={this.verifyCoupon}>Aplicar</button>
</div>
</div>
)
}
addProduct = (product) => {
let productClone = [...this.state.selectedProducts, product];
this.setState({selectedProducts: productClone}, () => console.log(this.state.selectedProducts));
this.updateLocalstorage(productClone, "selectedProducts");
}
removeProduct = (product) => {
let newProducts = this.state.selectedProducts.filter(p => p !== product);
this.setState({selectedProducts: newProducts});
this.updateLocalstorage(newProducts, "selectedProducts");
}
totalPrice = () => {
let total = this.state.selectedProducts.reduce((acum, item) => acum + item.price, 0);
if(this.state.isCouponValid){
total *= 0.9;
}
return total;
}
handleChange = (e) =>{
let couponValue = e.target.value;
this.setState({couponName: couponValue});
}
verifyCoupon = () =>{
if(this.state.couponName === "SAVE10"){
this.setState({isCouponValid: true})
this.updateLocalstorage(true, "isCouponValid");
}else{
alert("Cupón caducado, listillo")
}
}
updateLocalstorage = (data, attr) => {
localStorage[attr] = JSON.stringify(data);
}
}
import Btn from './../Btn/Btn'
import styled from 'styled-components'
const MiBtn = styled(Btn)`
${props => props.primary && css`
color: green;
`}
`
export default props => {
return(
<MiBtn {...props} />
)
}
import React from 'react'
class App extends React.Component {
state = {
username: '',
password: '',
}
handleChange = e => {
this.setState({ [e.target.name]: e.target.value })
}
isValid = () => {
return this.state.username && this.state.password && this.state.password.length >= 8
}
handleSubmit = (e) => {
e.preventDefault()
console.log(this.state)
}
render() {
return (
<form onSubmit={this.handleSubmit} onChange={this.handleChange}>
<input name="username" type="text" />
<input name="password" type="password" />
<button disabled={!this.isValid()}>Login</button>
</form>
)
}
}
export default App
import React from 'react'
import InputText from './InputText'
import List from './List'
import Button from './../clase1_2/Button'
class ListContainer extends React.Component {
state = {
todos: [{ id: 1, title: 'Ir a por el pan' }],
newTodoText: ''
}
handleInputChange = e => {
this.setState({ newTodoText: e.target.value })
}
onAddTodo = () => {
this.setState(state => ({
todos: [...state.todos, { id: Math.random(), title: state.newTodoText }],
newTodoText: '',
}))
}
onDeleteTask = (id) => {
this.setState({ todos: this.state.todos.filter(todo => todo.id !== id) })
}
onEditTodo = (e, id) => {
const value = e.target.value
const todosEdited = this.state.todos.map(todo => {
if (todo.id === id) todo.title = value
return todo
})
this.setState({ todos: todosEdited })
}
render() {
return (
<>
<List
todos={this.state.todos}
onDeleteTodo={this.onDeleteTask}
onEditTodo={this.onEditTodo}
/>
<InputText value={this.state.newTodoText} onChange={this.handleInputChange} />
<Button onPress={this.onAddTodo}>Add todo</Button>
</>
)
}
}
export default ListContainer
```js
const List = props => <ul>
{props.todos.map(todo =>
<li key={todo.id}>
<input type="text" onChange={e => props.onEditTodo(e, todo.id)} value={todo.title} />
<button onClick={() => props.onDeleteTodo(todo.id)}>Borrar</button>
</li>
)}
</ul>
export default List
const Button = (props) => <button onClick={props.onPress}>{props.children}</button>
export default Button
const InputText = props => <input type="text" value={props.value} onChange={props.onChange} />
export default InputText
import React from 'react'
import CheckPassword from './CheckPassword'
class LoginForm extends React.Component {
state = {
password: ''
}
handleChange = e => {
this.setState({
password: e.target.value
})
}
render() {
return (
<>
<input type="text" value={this.state.password} onChange={this.handleChange} />
<CheckPassword password={this.state.password} />
</>
)
}
}
export default LoginForm
import React from 'react'
export default props => {
let texto = ''
let points = 0
if (!props.password) {
texto = 'no hay contraseña'
}
if (props.password.length >= 8) points++
if (/[0-9]/.test(props.password)) points++
if (/[A-Z]/.test(props.password)) points++
if (/[$%&/()+-]/.test(props.password)) points++
if (points === 0 && props.password) texto = 'contraseña muy debil'
if (points === 1) texto = 'contraseña débil'
if (points > 1 && points <= 3) texto = 'contraseña media'
if (points >= 4) texto = 'contraseña fuerte'
return (
<p>{texto}</p>
)
}
App.js
<Title text="Necesito partir en componentes todo esto" />
<Text>Para ello puedo usar React que me permitirá poder reutilizar todos esos componentes. Para ello tengo que:</Text>
<List>
<ListItem>Observar el HTML</ListItem>
<ListItem>Pensar en como puedo extraer cada trozo en componentes</ListItem>
<ListItem>Usarlos en React</ListItem>
</List>
<Link to="https://reactjs.org/" text="React Docs" />
Title.js
import React from 'react'
export default props => <h1>{props.text}</h1>
Text.js
import React from 'react'
export default props =>
<p>{props.children}</p>
List.js
import React from 'react'
export default props =>
<ul>
{props.children}
</ul>
ListItem.js
import React from 'react'
export default props => <li>{props.children}</li>
Link.js
import React from 'react'
export default props =>
<a href={props.to} target={props.openInNewTab ? '_blank' : '_self'}>{props.text}</a>
import React from 'react'
class Chrono extends React.Component {
state = {
count: 0
}
countInterval = null
componentWillUnmount() {
this.stop()
}
start = () => {
this.countInterval = setInterval(() => {
this.setState(state => ({ count: state.count + 1 }))
console.log('actualizado')
}, 1000)
}
stop = () => clearInterval(this.countInterval)
render() {
return (
<>
<h1>{this.state.count}</h1>
<button onClick={this.start}>Start</button>
<button onClick={this.stop}>Stop</button>
</>
)
}
}
export default Chrono
TodoList.js
import React, { useState, useEffect } from 'react'
import useApiCall from './useApiCall'
export default () => {
const [todos, loading] = useApiCall('https://jsonplaceholder.typicode.com/todos')
return (
<>
<h1>Todos</h1>
<ul>
{todos && todos.map(todo => (
<li key={todo.id}>
{todo.title}
</li>
))}
</ul>
</>
)
}
useApiCall.js
import { useState, useEffect } from 'react'
export default url => {
const [data, setData] = useState(null)
const [loading, setLoading] = useState(false)
const fetchData = async (url) => {
setLoading(true)
let response = await fetch(url)
let data = await response.json()
setData(data)
setLoading(false)
}
useEffect(() => {
fetchData(url)
}, [url])
return [data, loading]
}
import React, { useState, useEffect } from 'react'
export default () => {
const [todos, setTodos] = useState([])
const fetchTodos = async () => {
let response = await fetch('https://jsonplaceholder.typicode.com/todos')
let data = await response.json()
setTodos(data)
}
useEffect(() => {
fetchTodos()
}, [])
return (
<>
<h1>Todos</h1>
<ul>
{todos.map(todo => (
<li key={todo.id}>
{todo.title}
</li>
))}
</ul>
</>
)
}
App.js:
import React from 'react';
import logo from './logo.svg';
import './App.css';
import Test from './Test';
class App extends React.Component {
state = {
status: false
}
toggleTestComponent = () => {
this.setState({ status: !this.state.status })
}
render() {
return (
<div className="App">
<header className="App-header">
{this.state.status ? <Test /> : ''}
<button onClick={this.toggleTestComponent}>Mostrar/ocultar</button>
</header>
</div>
);
}
}
export default App;
Test.js:
import React, { Component } from 'react'
class Test extends Component {
state = {
users: ['sergio', 'zamarro']
}
componentDidMount() {
let users = [...this.state.users]
users.push('otro')
this.setState({ users })
}
render() {
return JSON.stringify(this.state.users)
}
componentWillUnmount() {
console.log('Me destruyo!')
}
}
export default Test
`
/App.js/
import React, { useState } from 'react';
import AppContext from './AppContext';
import Header from './Header'
import Content from './Content'
function App() {
const [language, setLanguage] = useState('es')
return (
/AppContext.js/
import React from 'react';
export default React.createContext({language:'es', changeLanguage:()=>{}});
/Header.js/
import React, { useContext } from 'react'
import AppContext from './AppContext'
export default props => {
const context = useContext(AppContext)
return (
/Content.js/
import React from 'react';
import ContentText from './ContentText'
import ContentButton from './ContentButton'
function Content(){
return(
/* ContentText.js*/
import React from 'react';
import AppContext from './AppContext'
class ContentText extends React.Component{
static contextType = AppContext;
render(){
return(
<p>
{this.context.language==='es' ? "Hola" : "Hello"}
</p>
)
}
}
export default ContentText;
/* ContentButton.js*/
import React, {useContext} from 'react';
import AppContext from './AppContext';
function ContentButton(){
const context = useContext(AppContext);
return(
{context.language==='es' ? "Púlsame" : "Click me"}
)
}
export default ContentButton;
`
import React from 'react'
const List = props =>
<ul>
{props.children}
</ul>
const ListItem = props =>
<li>
<InputText onChange={(e) => props.onChange(e, props.task.id)} value={props.task.text} />
<BasicButton onClick={() => props.onDelete(props.task.text)} label="Borrar" />
</li>
const InputText = props =>
<input type="text" value={props.value} onChange={props.onChange} />
const Button = props =>
<button onClick={props.onClick}>{props.label}</button>
const AddTaskButton = props =>
<Button onClick={props.onClick} label={'Añadir boton'}/>
const BasicButton = props =>
<button style={{backgroundColor: props.action ? 'green' : 'orange'}} onClick={props.onClick}>{props.label}</button>
export default class ListContainer extends React.Component {
state = {
tasks: [{
id: 1,
text: 'zamarro'
}],
text: '',
}
addTask = () => {
this.setState({ tasks: [...this.state.tasks, this.state.text] })
}
deleteTask = (text) => {
let newTasks = this.state.tasks.filter(el => el !== text)
this.setState({ tasks: newTasks })
}
onChangeTask = (e, id) => {
let tasks = this.state.tasks.map(element => {
if (element.id === id) element.text = e.target.value
return element
})
this.setState({ tasks: tasks })
}
render() {
return(
<>
<List>
{this.state.tasks.map((element) => (
<ListItem
onDelete={this.deleteTask}
onChange={this.onChangeTask}
task={element}
key={element}
/>
))}
</List>
<InpuText type="text" onChange={e => this.setState({ text: e.target.value })} />
<BasicButton onClick={this.addTask} label="Añadir tarea" action="success" />
</>
)
}
}
Bueno, aquí debajo puedes ver opiniones de las personas que han hecho el curso conmigo. Seguro que habrá alguna mala pero espero que la mayoría sean buenas ❤️
Espero que esto me ayude a mejorar y también para que las demás personas se hagan una idea de cómo es el curso :)
import React from 'react'
import { Link, useParams } from 'react-router-dom'
export function Home() {
return (
<h1>Qué pasa</h1>
)
}
export function Users() {
return (
<ul>
<li>
<Link to="/users/roberto">Roberto</Link>
</li>
<li>
<Link to="/users/diana">Diana</Link>
</li>
</ul>
)
}
export function UserDetail() {
const {id} = useParams();
return (
<h2>
Hola {id}
</h2>
)
}
export function NotFound() {
return (
<div>
Ande vas?
</div>
)
}
```
`import React, { useState, useEffect } from 'react';
const Form = () => {
const [ nombre, setNombre ] = useState('')
const [ showError, setShowError ] = useState(false)
useEffect(() => {
if (nombre == 'zamarro') {
setShowError(true)
} else {
setShowError (false)
}
}, [nombre])
return (
<form>
<input
type="text"
value={nombre}
onChange={e => setNombre(e.target.value)}
/>
{ !showError && <span>error</span> }
</form>
);
};
export default Form;`
Child.js
import React from 'react'
export default class Child extends React.Component {
state = {
text: 'hola desde el hijo'
}
pepino = () => {
this.props.holi(this.state.text)
}
render() {
return (
<>
<h1>{this.state.text}</h1>
<button onClick={this.pepino}>holi</button>
</>
)
}
}
Form.js
import React from 'react'
import { getHobbies } from './helpers'
import Child from './Child'
export default class Form extends React.Component {
state = {
name: '',
firstName: '',
description: '',
gender: '',
age: 0,
country: '',
province: '',
hobbies: []
}
handleChange = (e) => {
let name = e.target.name
let value = e.target.value
if (e.target.type === 'checkbox') {
value = getHobbies(e.target.value, e.target.checked, this.state.hobbies)
}
this.setState({
[name]: value
})
}
handleSubmit = e => {
console.log(this.state)
e.preventDefault()
}
holi = data => {
console.log(data)
}
render() {
return (
<form onChange={this.handleChange} onSubmit={this.handleSubmit}>
<input type="text" name="name" />
<input type="text" name="firstName" />
<textarea name="description" />
<input type="radio" name="gender" value="male" /> Male
<input type="radio" name="gender" value="female" /> Female
<input type="number" name="age" />
<select name="country">
<option>Select one</option>
<option value="spain">Spain</option>
<option value="usa">USA</option>
</select>
{this.state.country === 'spain' && (
<select name="province">
<option>Select one</option>
<option value="guadalajara">Guadalajara</option>
<option value="madrid">Madrid</option>
</select>
)}
<label>
<input name="hobbies" type="checkbox" value="Games" />
Games
</label>
<label>
<input name="hobbies" type="checkbox" value="Football" />
Football
</label>
<label>
<input name="hobbies" type="checkbox" value="Basketball" />
Basketball
</label>
<label>
<input name="hobbies" type="checkbox" value="Art" />
Art
</label>
<Child holi={this.holi} />
<button type="submit">Enviar</button>
</form>
)
}
}
helpers.js
export const getHobbies = (hobby, checked, hobbies) => {
if (checked) {
return [...hobbies, hobby]
} else {
return hobbies.filter(h => h !== hobby)
}
}
//[{price: 500}, {price: 250}]
export const getPrice = products => {
return products.reduce((prev, current) => prev + current.price, 0)
}
helpers.test.js
const { getHobbies, getPrice } = require("./helpers")
test('Should remove football from array', () => {
expect(getHobbies('football', false, ['football']).length).toBe(0)
expect(getHobbies('football', false, ['football'])).not.toContain('football')
})
test('Should add football from array', () => {
expect(getHobbies('football', true, ['basketball']).length).toBe(2)
expect(getHobbies('football', true, ['basketball'])).toContain('football')
expect(getHobbies('football', true, ['basketball'])).toContain('basketball')
})
test('Should return 0 if products is an empty array', () => {
expect(getPrice([])).toBe(0)
})
test('Should return 500', () => {
const products = [{ price: 250 }, { price: 250 }]
expect(getPrice(products)).toBe(500)
})
import React from 'react';
import logo from './logo.svg';
import './App.css';
import Test from './Test';
class App extends React.Component {
state = {
name: '',
age: ''
}
toggleTestComponent = () => {
this.setState({ status: !this.state.status })
}
handleChange = (e) => {
this.setState({ [e.target.name]: e.target.value })
}
render() {
return (
<div className="App">
<header className="App-header">
<input type="text" name="name" value={this.state.name} onChange={this.handleChange}/>
<input type="text" name="age" value={this.state.age} onChange={this.handleChange}/>
</header>
</div>
);
}
}
export default App;
Hola!
Estoy tratando de animar el desplazamiento horizontal de un elemento con scrollLeft hasta 100px cuando hago click en un boton.
He creado una referencia al elemento con
const contenedorPreguntas = useRef();
y referenciado el elemento
<div ref={contenedorPreguntas} >
He creado un estado para tener seguimiento de por donde va el scroll:
const [scrollX, setScrollX] = useState(0);
Y con un boton que ejecute el scroll
<button onClick={scrollH}>Mover</button>
Y la función
const scrollH = (e) => {
if(scrollX<100){
contenedorPreguntas.current.scrollLeft += 1;
setScrollX(scrollX+1);
setTimeout(function(){ scrollH(); },100);
}
}
El scroll funciona pero no para nunca, ya que scrollX siempre está a 0, y setScrollX no hace cambiar el valor, únicamente la primera vez que pincha el usuario. Me gustaría entender el funcionamiento y cómo solucionarlo. Gracias!
import React from 'react'
import CheckboxGroup from './CheckboxGroup'
export default props =>
<>
<label>Hobbies</label>
<CheckboxGroup {...props} />
</>
import React from 'react'
export default props =>
<>
{props.items.map((item) => (
<span key={item}>
<input checked={props.selectedItems.includes(item)} type="checkbox" onChange={props.onChange} value={item} />
{item}
</span>
))}
</>
import React from 'react'
import InputText from './InputText'
import Textarea from './Textarea'
import GenderPicker from './GenderPicker'
import Select from './Select'
import ConditionalRender from './ConditionalRender'
import HobbiesPicker from './HobbiesPicker'
import CheckboxGroup from './CheckboxGroup'
export class Form extends React.Component {
state = {
name: '',
firstname: '',
description: '',
gender: 'female',
age: 27,
selectedCountry: 'es',
selectedProvince: 'guadalajara',
selectedHobbies: ['games']
}
countries = [
{
value: 'es',
text: 'Spain'
},
{
value: 'usa',
text: 'USA'
}
]
provinces = [
{
value: 'guadalajara',
text: 'Guadalajara'
},
{
value: 'madrid',
text: 'Madrid'
}
]
hobbies = ['games', 'football', 'basketball', 'art']
handleChangeInput = (e) => {
this.setState({
[e.target.name]: e.target.value
})
}
printState = (e) => {
console.log(this.state)
e.preventDefault()
}
onChangeHobbies = (e) => {
if (e.target.checked) {
this.setState({ selectedHobbies: [...this.state.selectedHobbies, e.target.value] })
} else {
this.setState({ selectedHobbies: this.state.selectedHobbies.filter(hobby => hobby !== e.target.value) })
}
}
render() {
return(
<form onSubmit={this.printState}>
<InputText
label="Name"
name="name"
value={this.state.name}
onChange={this.handleChangeInput}
/>
<br />
<InputText
label="Firstname"
name="firstname"
value={this.state.firstname}
onChange={this.handleChangeInput}
/>
<br />
<Textarea
value={this.state.description}
onChange={this.handleChangeInput}
name="description"
label="Description"
/>
<br />
<GenderPicker
onChange={this.handleChangeInput}
label="Gender"
value={this.state.gender}
/>
<br />
<InputText
value={this.state.age}
onChange={this.handleChangeInput}
type="number"
name="age"
label="Age"
/>
<br />
<Select
items={this.countries}
value={this.state.selectedCountry}
name="selectedCountry"
onChange={this.handleChangeInput}
/>
<br />
<ConditionalRender if={this.state.selectedCountry === 'es'}>
<Select
items={this.provinces}
value={this.state.selectedProvince}
name="selectedProvince"
onChange={this.handleChangeInput}
/>
</ConditionalRender>
<HobbiesPicker
items={this.hobbies}
onChange={this.onChangeHobbies}
selectedItems={this.state.selectedHobbies}
/>
<button type="submit">Enviar</button>
</form>
)
}
}
ListContainer.js
import React from 'react'
import List from './List'
import InputText from './InputText'
import AddTaskButton from './AddTaskButton'
class ListContainer extends React.Component {
state = {
tasks: [{
id: 10001,
title: 'Comprar el pan'
}, {
id: 10002,
title: 'Sacar a India'
}],
newTaskText: ''
}
handleNewTaskText = e => {
this.setState({ newTaskText: e.target.value })
}
addTask = () => {
this.setState({
tasks: [...this.state.tasks, { id: Math.random(), title: this.state.newTaskText }],
newTaskText: '',
})
}
removeTask = taskId => {
let newTasks = this.state.tasks.filter(task => task.id !== taskId)
this.setState({ tasks: newTasks })
}
render() {
return (
<>
<List tasks={this.state.tasks} onRemove={this.removeTask} />
<InputText onChange={this.handleNewTaskText} value={this.state.newTaskText} />
<AddTaskButton onAdd={this.addTask} />
</>
)
}
}
export default ListContainer
List.js
import React from 'react'
import ListItem from './ListItem'
export default props =>
<ul>
{props.tasks.map(task => (
<ListItem key={task.id} title={task.title} onRemove={() => props.onRemove(task.id)} />
))}
</ul>
ListItem.js
import React from 'react'
import RemoveTaskButton from './RemoveTaskButton'
export default props =>
<>
<li>
<p contentEditable={true}>{props.title}</p>
</li>
<RemoveTaskButton onRemove={props.onRemove} />
</>
InputText.js
import React from 'react'
export default props => <input type="text" value={props.value} onChange={props.onChange} />
AddTaskButton.js
import React from 'react'
export default props => <button onClick={props.onAdd}>Add task</button>
ShopPage.js
import React from 'react'
import productsConstants from './products.constants'
import ProductsList from './ProductsList'
import { getPrice } from './helpers'
class ShopPage extends React.Component {
state = {
selectedProducts: [],
discountCode: '',
applyDiscount: false,
}
componentDidMount() {
const selectedProducts = this.getProductsFormLocalStorage()
this.setState({ selectedProducts })
}
addProduct = product => {
const newProducts = [...this.state.selectedProducts, product]
this.setProductsInLocalStorage(newProducts)
this.setState({
selectedProducts: newProducts
})
}
removeProduct = product => {
const newProducts = this.state.selectedProducts.filter(p => p.id !== product.id)
this.setProductsInLocalStorage(newProducts)
this.setState({
selectedProducts: newProducts
})
}
setProductsInLocalStorage = products => {
localStorage.selectedProducts = JSON.stringify(products)
}
getProductsFormLocalStorage = () => {
const selectProducts = localStorage.selectedProducts
if (selectProducts) return JSON.parse(localStorage.selectedProducts)
return []
}
handleChangeDiscountCode = e => {
this.setState({
discountCode: e.target.value
})
}
validateDiscountCode = () => {
if (this.state.discountCode === 'SAVE10') {
this.setState({ applyDiscount: true })
} else {
this.setState({ applyDiscount: false })
}
}
render() {
return (
<div className="shopContainer">
<div>
<h1>Products</h1>
<ProductsList products={productsConstants} button={product => <button onClick={() => this.addProduct(product)}>Add product</button>} />
</div>
<div>
<h1>Selected Products</h1>
<ProductsList products={this.state.selectedProducts} button={product => <button onClick={() => this.removeProduct(product)}>Remove product</button>} />
<input type="text" onChange={this.handleChangeDiscountCode}/>
<button onClick={this.validateDiscountCode}>Validate discount code</button>
{this.state.selectedProducts.length > 0 && <p>Total: {this.state.applyDiscount ? getPrice(this.state.selectedProducts) * 0.90 : getPrice(this.state.selectedProducts)}€</p>}
</div>
</div>
)
}
}
export default ShopPage
ProductList.js
import React from 'react'
export default props => {
return (
props.products.map(product => (
<div key={product.id}>
{product.name} - {product.price}
{props.button(product)}
</div>
))
)
}
export const editTodo = (todos, value, id) => {
return todos.map(todo => {
if (todo.id === id) todo.title = value
return todo
})
}
import { editTodo } from "./helpers"
test('Should edit a todo', () => {
const todos = [{ id: 1, title: 'hola' }]
const newMessage = 'editado!'
const newTodos = editTodo(todos, newMessage, todos[0].id)
expect(newTodos[0].title).toBe(newMessage)
})
import React from 'react'
import './../App.css'
import ProductList from './ProductList'
import products from './products.constants'
class Shop extends React.Component {
state = {
selectedProducts: [],
discountCode: '',
applyDiscount: false,
}
componentDidMount() {
if (localStorage.state) {
this.setState(JSON.parse(localStorage.state))
}
}
componentDidUpdate() {
localStorage.state = JSON.stringify(this.state)
}
onAddProduct = product => {
this.setState({ selectedProducts: [...this.state.selectedProducts, product] })
}
onRemoveProduct = product => {
this.setState({ selectedProducts: this.state.selectedProducts.filter(p => p.id !== product.id) })
}
getTotalPrice = () => {
const result = this.state.selectedProducts.reduce((acum, next) => acum + next.price, 0)
return this.state.applyDiscount ? result * 0.90 : result
}
handleChangeDiscountCode = e => {
this.setState({ discountCode: e.target.value })
}
onApplyDiscount = () => {
this.setState({ applyDiscount: this.state.discountCode === 'SAVE10' })
}
render() {
return (
<>
<h1>Shop</h1>
<div className="shop-container">
<div>
Products:
<ProductList
products={products}
action={(product) => <button onClick={() => this.onAddProduct(product)}>Add</button>}
/>
</div>
<div>
Selected Products:
<ProductList
products={this.state.selectedProducts}
action={(product) => <button onClick={() => this.onRemoveProduct(product)}>Remove</button>}
/>
<h1>Total: {this.getTotalPrice()}</h1>
<input value={this.state.discountCode} onChange={this.handleChangeDiscountCode} type="text" />
<button onClick={this.onApplyDiscount}>Apply discount</button>
</div>
</div>
</>
)
}
}
export default Shop
const ProductList = props => props.products.map(product => (
<div key={product.id}>
<img src={product.img} alt="iphone" height="100" />
<p>Name: {product.name}</p>
<p>Price: {product.price}</p>
{props.action(product)}
</div>
))
export default ProductList
const products = [
{
id: 1,
name: 'iPhone X',
price: 900,
img: 'https://thumb.pccomponentes.com/w-300-300/articles/32/328890/1391-apple-iphone-12-pro-max-256gb-azul-pacifico-libre.jpg'
},
{
id: 2,
name: 'iPhone 12',
price: 1200,
img: 'https://thumb.pccomponentes.com/w-300-300/articles/32/328889/1312-apple-iphone-12-pro-max-256gb-oro-libre.jpg'
},
{
id: 3,
name: 'iPhone 13',
price: 1500,
img: 'https://thumb.pccomponentes.com/w-300-300/articles/32/328931/1319-apple-iphone-12-128gb-product-rojo-libre.jpg'
},
]
export default products
Button.js
import React from 'react'
export default props =>
<button onClick={props.onPress}>{props.label}</button>
Chronometer.js
import React from 'react'
export default class Chronometer extends React.Component {
state = {
count: 0
}
updateStateInterval = null
componentDidMount() {
console.log('holi!')
}
componentDidUpdate(prevProps, prevState) {
console.log(prevProps, prevState)
}
startChrono = () => {
setTimeout(() => {
this.setState({count: this.state.count + 1})
}, 1000)
setInterval(() => {
this.setState({count: this.state.count + 1})
}, 2000)
}
componentWillUnmount() {
console.log('me voy!')
clearInterval(this.updateStateInterval)
}
render() {
return (
<>
<h1>{this.state.count}</h1>
<button onClick={this.startChrono}>Start</button>
</>
)
}
}
Counter.js
import React, { Component } from 'react'
import Title from './Title'
import Button from './Button'
class Counter extends Component {
state = {
count: 0,
}
handleChange = action => {
this.setState(prevState =>
({ count: action === 'increment' ? prevState.count + 1 : prevState.count - 1 })
)
}
render() {
return (
<>
<Title text={this.state.count} />
<Button onPress={() => this.handleChange('increment')} label="Increment"/>
<Button onPress={() => this.handleChange('decrement')} label="Decrement"/>
</>
)
}
}
export default Counter
CounterText.js
import React, { Component } from 'react'
class CounterText extends Component {
state = {
text: '',
}
increment = () => {
this.setState(prevState => ({ text: prevState.text + 'a' }))
}
decrement = () => {
this.setState(prevState => ({ text: prevState.text.slice(1) }))
}
render() {
return (
<>
<div>{this.state.text}</div>
<button onClick={this.increment}>Increment</button>
<button onClick={this.decrement}>Decrement</button>
</>
)
}
}
export default CounterText
Input.js
import React from 'react'
export default () => <input type="text" onChange={e => console.log(e.target.value)} />
Likes.js
import React from 'react'
export default class Likes extends React.Component {
state = {
likes: 50,
liked: false
}
handleChange = () => {
this.setState(prevState => ({
liked: !prevState.liked,
likes: prevState.liked ? prevState.likes-- : prevState.likes++
}))
}
render() {
return (
<>
<h1>{this.state.likes}</h1>
<button onClick={this.handleChange}>{this.state.liked ? 'Dislike' : 'Like'}</button>
</>
)
}
}
LogProps.js
import React from 'react'
export default props => {
console.log(props)
return(
<p>Mira las developers tools</p>
)
}
Password.js
import React from 'react'
export default class Password extends React.Component {
state = {
show: false
}
togglePassword = () => {
this.setState(prevState => ({ show: !prevState.show }))
}
render() {
return (
<>
<input type={this.state.show ? 'text' : 'password'} />
<button onClick={this.togglePassword}>Toggle</button>
</>
)
}
}
Title.js
import React from 'react'
const Title = (props) => <h1>{props.text}</h1>
export default Title
import React from 'react'
class App extends React.Component {
state = {
text: ''
}
changeText = (e) => this.setState({ text: e.target.value })
render() {
return <>
<h1>{this.state.text}</h1>
<input type="text" onChange={this.changeText} />
</>
}
}
export default App
import React from 'react'
class Chronometer extends React.Component {
state = {
count: 0
}
startChronometer = () => {
setInterval(() => {
this.setState(prevState => ({ count: prevState.count + 1 }))
}, 1000)
}
render() {
return (
<>
<h1>{this.state.count}</h1>
<button onClick={this.startChronometer}>Start</button>
</>
)
}
}
export default Chronometer
import React from 'react'
const PasswordStrength = props => {
let texto = ''
let points = 0
if (!props.password) {
texto = 'no hay contraseña'
}
if (props.password.length >= 8) points++
if (/[0-9]/.test(props.password)) points++
if (/[A-Z]/.test(props.password)) points++
if (/[$%&/()+-]/.test(props.password)) points++
if (points === 0 && props.password) texto = 'contraseña muy débil'
if (points === 1) texto = 'contraseña débil'
if (points > 1 && points <= 3) texto = 'contraseña media'
if (points >= 4) texto = 'contraseña fuerte'
return (
<p>{texto}</p>
)
}
export default PasswordStrength
Greeting.js
import React from 'react'
const Greeting = props => <h1>{props.children}</h1>
export default Greeting
Link.js
import React from 'react'
export default props =>
<a href={props.to} target={props.openInNewTab ? '_blank' : '_self'}>{props.text}</a>
List.js
import React from 'react'
export default props =>
<ul>
{props.children}
</ul>
ListItem.js
import React from 'react'
export default props => <li>{props.children}</li>
Loading.js
export default props => props.show ? props.children : 'Loading...'
ShowName.js
import React from 'react'
const ShowName = props => <p>{props.user.name} - {props.age}</p>
export default ShowName
TestChildren.js
import React from 'react'
const TestChildren = props =>
<>
<div>hola1</div>
<div>hola2</div>
</>
export default TestChildren
Text.js
import React from 'react'
export default props =>
<p>{props.children}</p>
Title.js
import React from 'react'
export default props => <h1>{props.text}</h1>
import React, {useState,Suspense} from 'react';
const Counter = React.lazy(() => import('./Counter'))
function App() {
const [load, setLoad] = useState(false);
return (
<div className="App">
<header className="App-header">
<button onClick={()=>setLoad(!load)}>Toggle</button>
{load &&
<Suspense fallback={<div>Loading...</div>}>
<Counter/>
</Suspense>
}
</header>
</div>
)
}
export default App;
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.