https://www.techiediaries.com/react-json-fetch-rest-api-bootstrap/
https://pusher.com/tutorials/consume-restful-api-react
Categoría: JavaScript
La guía más completa de destructuring en Java Script
https://buginit.com/javascript/javascript-destructuring-es6-the-complete-guide/
Con ejemplos ilustrativos para desestructurar arrays y objetos.
Bonus track: 10 librerías útiles de JavaScript
https://www.arquitecturajava.com/10-javascript-helper-libraries-que-nos-ayudan/
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
}));
Ejercicio (I)
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class Boton extends Component {
mas = () => {
this.props.mas(0);
}
render() {
return (
<button onClick={this.mas}>+</button>
);
}
}
;
class Fila extends Component {
menos = () => {
this.props.menos(this.props.indice);
}
render() {
return (
<p><input type="number" value={this.props.valor}></input>
<button onClick={this.menos}>-</button>
</p>
);
}
}
class Total extends Component {
render() {
return (
<p>Total:{this.props.suma}</p>
)
}
}
class Tabla extends Component {
constructor(props) {
super(props);
this.state = {
numeros: [1, 2, 90, 0, 45]
};
}
mas = (valor) => {
this.setState({ numeros: [...this.state.numeros, valor] });
}
menos = (index) => {
this.setState({
numeros: this.state.numeros.filter((numero, i) => i != index)
});
}
render() {
const filas = this.state.numeros.map((valor, index) => {
return (<Fila key={index} indice={index} valor={valor} menos={this.menos} />);
});
const suma = this.state.numeros.reduce((a, b) => a + b, 0);
return (
<div>
<Boton mas={this.mas} />
{filas}
<Total suma={suma} />
</div>
);
}
}
;
class App extends Component {
render() {
return (
<Tabla />
);
}
}
;
export default App;
Etiqueta color
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class Cuadrado extends Component {
render() {
const estilo = {
padding: 10,
margin: 20,
display: "inline-block",
backgroundColor: this.props.bgColor,
width: 100,
height: 100
};
return (
<div style={estilo}>
</div>
);
}
}
class Color extends Component {
constructor(props) {
super(props);
this.state = {
color: this.props.color
};
}
cambio = (event) => {
const {name, value} = event.target;
this.setState({
[name]: value
})
this.props.cambiaColor(value);
}
render() {
return (
<div>
<input type="text" name="color" value={this.state.color} onChange={this.cambio}/>
</div>
);
}
}
class Tarjeta extends Component {
constructor(props) {
super(props);
this.state = {
color: "red"
};
}
isColor = (strColor) => {
const s = new Option().style;
s.color = strColor;
return s.color !== '';
}
shouldComponentUpdate(nextProps, nextState) {
return this.isColor(nextState.color);
}
cambiaColor = (color) => {
this.setState({color: color});
}
render() {
return (
<div>
<Cuadrado bgColor={this.state.color}/>
<Color color={this.state.color} cambiaColor={this.cambiaColor}/>
</div>
);
}
}
;
class App extends Component
{
render() {
return (
<Tarjeta/>
);
}
}
export default App;
Ciclo de vida de los componentes
Aquí están muy bien explicados:
https://www.gistia.com/understand-react-lifecycle-methods/
Código:
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import logo from './logo.svg';
import './App.css';
class Contador extends React.Component {
render() {
var textStyle = {
fontSize: 72,
fontFamily: "sans-serif",
color: "#333",
fontWeight: "bold"
};
console.log("render: Contador componente");
return (
<div style={textStyle}>
{this.props.display}
</div>
);
}
}
class ContadorParent extends React.Component {
constructor(props) {
super(props);
console.log("constructor: Valores por defecto");
this.state = {
count: 0
};
this.increase = this.increase.bind(this);
}
increase() {
this.setState({
count: this.state.count + 1
});
}
static getDerivedStateFromProps(props, state) {
console.log("getDerivedStateFromProps: Poco uso")
return null;
}
componentDidUpdate(currentProps, currentState) {
console.log("componentDidUpdate: El componente se ha actualizado");
}
getSnapshotBeforeUpdate(prevProps, prevState) {
console.log("getSnapshotBeforeUpdate: El componente va a enviar sus cambios")
return null;
}
componentDidMount() {
console.log("componentDidMount: Componente insertado en el árbol DOM");
}
componentWillUnmount() {
console.log("componentWillUnmount: Component a punto de ser eliminado del DOM");
}
shouldComponentUpdate(newProps, newState) {
console.log("shouldComponentUpdate: ¿Hay que actualizar?");
if (newState.count < 5) {
console.log("shouldComponentUpdate: Sí, hay que actualizar");
return true;
} else {
ReactDOM.unmountComponentAtNode(document.getElementById('root'));
console.log("shouldComponentUpdate: No hay que actualizar");
return false;
}
}
render() {
var backgroundStyle = {
padding: 50,
border: "#333 2px dotted",
width: 250,
height: 100,
borderRadius: 10,
textAlign: "center"
};
console.log("render: ContadorParent componente");
return (
<div style={backgroundStyle}>
<Contador display={this.state.count} />
<button onClick={this.increase}>
+
</button>
</div>
);
}
}
;
class App extends Component
{
render() {
return (
<ContadorParent/>
);
}
}
;
export default App;
Formulario
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class Form extends Component {
constructor(props) {
super(props)
this.initialState = {
nombre: '',
nota: '',
}
this.state = this.initialState;
}
cambio = event => {
const {name, value} = event.target;
console.log(name + "|" + value);
this.setState({
[name]: value
})
}
enviar = () => {
this.props.mas(this.state.nombre, this.state.nota);
this.setState(this.initialState);
}
render() {
return (
<form>
<label>Nombre</label>
<input type="text" name="nombre" value={this.state.nombre} onChange={this.cambio} />
<label>Nota</label>
<input type="text" name="nota" value={this.state.nota} onChange={this.cambio} />
<input type="button" onClick={this.enviar} value="Añadir"/>
</form>
);
}
}
class Cabecera extends Component {
render() {
return (
<tr><th>Alumno</th><th>Nota</th></tr>
);
}
}
;
class Fila extends Component {
eliminar=(e)=>{
e.stopPropagation();
this.props.menos(this.props.indice);
}
render() {
return (
<tr onClick={() => this.props.mas(this.props.nombre, this.props.nota)}>
<td>{this.props.nombre}</td><td>{this.props.nota}</td>
<td><input type="button" value="Borrar" onClick={this.eliminar}/></td>
</tr>
);
}
}
;
class Tabla extends Component {
constructor(props) {
super(props);
this.state = {
alumnos: this.props.alumnos,
cont: 0
};
this.mas = this.mas.bind(this);
}
mas(nombre, nota) {
this.setState({alumnos: [...this.state.alumnos, {nombre: nombre, nota: nota}]});
}
menos = (index) => {
this.setState({
alumnos: this.state.alumnos.filter((alumno, i) => i != index)
});
}
render() {
const filas = this.state.alumnos.map((fila, index) => {
return (<Fila key={index} indice={index} nombre={fila.nombre} nota={fila.nota} menos={this.menos} mas={this.mas}/>);
}
);
return (
<div>
<Form mas={this.mas}/>
<button onClick={() => this.mas("Ana", 6)}>Añadir</button> <button onClick={() => this.menos(0)}>Quitar</button>
<table>
<thead>
<Cabecera/></thead>
<tbody>
{filas}
</tbody>
</table>
</div>
);
}
}
;
class App extends Component
{
render() {
const alumnos = [{nombre: "Ana", nota: 6}, {nombre: "Pep", nota: 4}, {nombre: "Eva", nota: 8}, {nombre: "Ot", nota: 7}];
return (
<Tabla alumnos={alumnos}/>
);
}
}
;
export default App;
Quitar elementos
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class Cabecera extends Component {
render() {
return (
<tr><th>Alumno</th><th>Nota</th></tr>
);
}
}
;
class Fila extends Component {
render() {
return (
<tr onClick={() => this.props.mas(this.props.nombre, this.props.nota)}>
<td>{this.props.nombre}</td><td>{this.props.nota}</td>
</tr>
);
}
}
;
class Tabla extends Component {
constructor(props) {
super(props);
this.state = {
alumnos: this.props.alumnos,
cont: 0
};
this.mas = this.mas.bind(this);
}
mas(nombre, nota) {
this.setState({alumnos: [...this.state.alumnos, {nombre: nombre, nota: nota}]});
}
menos=(index)=>{
this.setState({
alumnos:this.state.alumnos.filter((alumno,i)=>i!=index)
});
}
render() {
const filas = this.state.alumnos.map((fila, index) => {
return (<Fila key={index} nombre={fila.nombre} nota={fila.nota} mas={this.mas}/>);
}
);
return (
<div>
<button onClick={() => this.mas("Ana", 6)}>Añadir</button> <button onClick={() => this.menos(0)}>Quitar</button>
<table>
<thead>
<Cabecera/></thead>
<tbody>
[ {filas}
</tbody>
</table>
</div>
);
}
}
;
class App extends Component
{
render() {
const alumnos = [{nombre: "Ana", nota: 6}, {nombre: "Pep", nota: 4}, {nombre: "Eva", nota: 8}, {nombre: "Ot", nota: 7}];
return (
<Tabla alumnos={alumnos}/>
);
}
}
;
export default App;
Pasar funciones a componentes hijos
Un ejemplo:
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class Cabecera extends Component {
render() {
return (
<tr><th>Alumno</th><th>Nota</th></tr>
);
}
}
;
class Fila extends Component {
render() {
return (
<tr onClick={() => this.props.mas(this.props.nombre, this.props.nota)}>
<td>{this.props.nombre}</td><td>{this.props.nota}</td>
</tr>
);
}
}
;
class Tabla extends Component {
constructor(props) {
super(props);
this.state = {
alumnos: this.props.alumnos,
cont: 0
};
this.mas = this.mas.bind(this);
}
mas(nombre, nota) {
this.setState({alumnos: [...this.state.alumnos, {nombre: nombre, nota: nota}]});
}
render() {
const filas = this.state.alumnos.map((fila, index) => {
return (<Fila key={index} nombre={fila.nombre} nota={fila.nota} mas={this.mas}/>);
}
);
return (
<div>
<button onClick={() => this.mas("Ana", 6)}>Añadir</button>
<table>
<thead>
<Cabecera/></thead>
<tbody>
{filas}
</tbody>
</table>
</div>
);
}
}
;
class App extends Component
{
render() {
const alumnos = [{nombre: "Ana", nota: 6}, {nombre: "Pep", nota: 4}];
return (
<Tabla alumnos={alumnos}/>
);
}
}
;
export default App;
Ver círculo (II)
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class Circulo extends React.Component {
render() {
var circuloStyle = {
padding: 10,
margin: 20,
display: "inline-block",
backgroundColor: this.props.bgColor,
borderRadius: "50%",
width: 100,
height: 100,
};
return (
<div style={circuloStyle}>
</div>
);
}
}
function verCirculo(num) {
let colores = ["#393E41", "#E94F37", "#1C89BF", "#A1D363", "#FF2178","#e5d8bf","#00818a","#f54291","#ff0000"];
let circulos = [];
for (let i = 0; i < num; i++) {
let ran = Math.floor(Math.random() * colores.length);
circulos.push(<Circulo key={i} bgColor={colores[ran]} />);
}
return circulos;
}
class VerCirculo extends React.Component {
render() {
return verCirculo(this.props.num);
}
}
class App extends Component
{
constructor(props){
super(props);
this.state={cont:0};
}
foo=()=>{
this.setState({cont:this.state.cont+1});
}
render() {
return (
<div onClick={this.foo}>
<VerCirculo num="3"/>
{verCirculo(this.state.cont)}
</div>
);
}
}
export default App;