├── .eslintrc
├── .gitignore
├── README.md
├── package.json
├── public
├── favicon.ico
├── index.html
└── manifest.json
├── src
├── App.css
├── App.js
├── App.test.js
├── ContadorApp.js
├── data
│ └── cars.json
├── index.css
├── index.js
├── logo.svg
├── registerServiceWorker.js
└── sections
│ ├── children.js
│ ├── componentsWithComposition.js
│ ├── componentsWithInheritance.js
│ ├── conditional.js
│ ├── events.js
│ ├── fetch-example.js
│ ├── forms.js
│ ├── lists.js
│ └── stateless-proptypes.js
└── yarn.lock
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "react-app"
3 | }
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 |
6 | # testing
7 | /coverage
8 |
9 | # production
10 | /build
11 |
12 | # misc
13 | .DS_Store
14 | .env.local
15 | .env.development.local
16 | .env.test.local
17 | .env.production.local
18 |
19 | npm-debug.log*
20 | yarn-debug.log*
21 | yarn-error.log*
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Este repositorio está deprecado. Utiliza este que tiene archivos más actualizados. :)
2 | https://github.com/AprendiendoFrontend/Aprendiendo-React
3 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "udemy-curso",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "prop-types": "15.6.0",
7 | "react": "^15.6.1",
8 | "react-dom": "^15.6.1"
9 | },
10 | "devDependencies": {
11 | "react-scripts": "1.0.7"
12 | },
13 | "scripts": {
14 | "start": "react-scripts start",
15 | "build": "react-scripts build",
16 | "test": "react-scripts test --env=jsdom",
17 | "eject": "react-scripts eject"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/midudev/curso-udemy-react/7fe8e70b747b112676cb46a18a5d58ca08b95948/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 |
12 |
13 |
22 | React App
23 |
24 |
25 |
28 |
29 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "192x192",
8 | "type": "image/png"
9 | }
10 | ],
11 | "start_url": "./index.html",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | animation: App-logo-spin infinite 20s linear;
7 | height: 80px;
8 | }
9 |
10 | .App-header {
11 | background-color: #222;
12 | height: 150px;
13 | padding: 20px;
14 | color: white;
15 | }
16 |
17 | .App-intro {
18 | font-size: large;
19 | }
20 |
21 | @keyframes App-logo-spin {
22 | from { transform: rotate(0deg); }
23 | to { transform: rotate(360deg); }
24 | }
25 |
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import FetchExample from './sections/fetch-example'
3 |
4 | class App extends Component {
5 | render () {
6 | return (
7 |
8 |
9 |
10 | );
11 | }
12 | }
13 |
14 | export default App;
15 |
--------------------------------------------------------------------------------
/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 | it('renders without crashing', () => {
6 | const div = document.createElement('div');
7 | ReactDOM.render(, div);
8 | });
9 |
--------------------------------------------------------------------------------
/src/ContadorApp.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 |
3 | class Contador extends Component {
4 | constructor (props) {
5 | super(props)
6 | console.log(this.props.contadorInicial)
7 | this.state = { contador: this.props.contadorInicial }
8 | setInterval(() => {
9 | this.setState({ contador: this.state.contador + 1 })
10 | }, 1000)
11 | }
12 |
13 | render () {
14 | return
15 | }
16 | }
17 |
18 | Contador.defaultProps = {
19 | contadorInicial: 0
20 | }
21 |
22 | class ContadorNumero extends Component {
23 | render () {
24 | console.log('ContadorNumero render()')
25 | return {this.props.numero}
26 | }
27 | }
28 |
29 | class App extends Component {
30 | render () {
31 | return (
32 |
33 |
Propagando el state de nuestros componentes
34 |
35 |
36 | );
37 | }
38 | }
39 |
40 | export default App;
41 |
--------------------------------------------------------------------------------
/src/data/cars.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "efe1a0cd-8353-4ba0-d4v3-30434c933298",
4 | "name": "A3",
5 | "company": "Audi"
6 | },
7 | {
8 | "id": "9b9048ec-fff8-4bc5-m1k3-d0c65b83eb92",
9 | "name": "Mondeo",
10 | "company": "Ford"
11 | },
12 | {
13 | "id": "f447e8a1-26a2-4e3a-p3n3-724e93fd4945",
14 | "name": "Megane",
15 | "company": "Renault"
16 | },
17 | {
18 | "id": "52f1c5b7-14b5-41c0-t3t4-42ef853a7648",
19 | "name": "A200",
20 | "company": "Mercedes"
21 | }
22 | ]
23 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0 16px;
4 | font-family: sans-serif;
5 | }
6 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 | import registerServiceWorker from './registerServiceWorker';
5 | import './index.css';
6 |
7 | ReactDOM.render(, document.getElementById('root'));
8 | registerServiceWorker();
9 |
--------------------------------------------------------------------------------
/src/logo.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/registerServiceWorker.js:
--------------------------------------------------------------------------------
1 | // In production, we register a service worker to serve assets from local cache.
2 |
3 | // This lets the app load faster on subsequent visits in production, and gives
4 | // it offline capabilities. However, it also means that developers (and users)
5 | // will only see deployed updates on the "N+1" visit to a page, since previously
6 | // cached resources are updated in the background.
7 |
8 | // To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
9 | // This link also includes instructions on opting out of this behavior.
10 |
11 | export default function register() {
12 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
13 | window.addEventListener('load', () => {
14 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
15 | navigator.serviceWorker
16 | .register(swUrl)
17 | .then(registration => {
18 | registration.onupdatefound = () => {
19 | const installingWorker = registration.installing;
20 | installingWorker.onstatechange = () => {
21 | if (installingWorker.state === 'installed') {
22 | if (navigator.serviceWorker.controller) {
23 | // At this point, the old content will have been purged and
24 | // the fresh content will have been added to the cache.
25 | // It's the perfect time to display a "New content is
26 | // available; please refresh." message in your web app.
27 | console.log('New content is available; please refresh.');
28 | } else {
29 | // At this point, everything has been precached.
30 | // It's the perfect time to display a
31 | // "Content is cached for offline use." message.
32 | console.log('Content is cached for offline use.');
33 | }
34 | }
35 | };
36 | };
37 | })
38 | .catch(error => {
39 | console.error('Error during service worker registration:', error);
40 | });
41 | });
42 | }
43 | }
44 |
45 | export function unregister() {
46 | if ('serviceWorker' in navigator) {
47 | navigator.serviceWorker.ready.then(registration => {
48 | registration.unregister();
49 | });
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/sections/children.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 |
3 | class Box extends Component {
4 | render () {
5 | return (
6 |
7 | {this.props.children}
8 |
9 | )
10 | }
11 | }
12 |
13 | class Article extends Component {
14 | render () {
15 | return (
16 |
17 | {this.props.title}
18 | Escrito por {this.props.author}
19 | {this.props.date}
20 |
21 | {this.props.children}
22 |
23 |
24 | )
25 | }
26 | }
27 |
28 | class Children extends Component {
29 | render () {
30 | return (
31 |
32 |
Children props
33 |
38 | El contenido que envolvemos dentro del componente Article será enviado al componente como this.props.children.
39 | Y mantiene las etiquetas y componentes que hayáis añadido dentro
40 |
41 |
46 | El contenido que envolvemos dentro del componente Article será enviado al componente como this.props.children.
47 | Y mantiene las etiquetas y componentes que hayáis añadido dentro
48 |
49 |
54 | El contenido que envolvemos dentro del componente Article será enviado al componente como this.props.children.
55 | Y mantiene las etiquetas y componentes que hayáis añadido dentro
56 |
57 |
58 | );
59 | }
60 | }
61 |
62 | export default Children;
63 |
--------------------------------------------------------------------------------
/src/sections/componentsWithComposition.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 |
3 | class Button extends Component {
4 | render () {
5 | return (
6 |
9 | )
10 | }
11 | }
12 |
13 | Button.defaultProps = {
14 | borderColor: '#09f'
15 | }
16 |
17 | class ButtonDanger extends Component {
18 | render () {
19 | return
20 | }
21 | }
22 |
23 | class ButtonWithLegend extends Component {
24 | render () {
25 | return (
26 |
27 |
28 | {this.props.legend}
29 |
30 | )
31 | }
32 | }
33 |
34 | class ComponentsWithComposition extends Component {
35 | render () {
36 | return (
37 |
38 |
Composición vs. herencia (ejemplo de composición)
39 |
40 |
41 |
42 |
43 |
46 |
47 | );
48 | }
49 | }
50 |
51 | export default ComponentsWithComposition;
52 |
--------------------------------------------------------------------------------
/src/sections/componentsWithInheritance.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 |
3 | class Button extends Component {
4 | constructor (props) {
5 | super(props)
6 | this.borderColor = '#09f'
7 | }
8 |
9 | render () {
10 | return (
11 |
14 | )
15 | }
16 | }
17 |
18 | class ButtonDanger extends Button {
19 | constructor (props) {
20 | super(props)
21 | this.borderColor = 'red'
22 | }
23 | }
24 |
25 | class ButtonWithLegend extends Button {
26 | render () {
27 | return (
28 |
29 | {super.render()}
30 | {this.props.legend}
31 |
32 | )
33 | }
34 | }
35 |
36 | class ComponentsWithInheritance extends Component {
37 | render () {
38 | return (
39 |
40 |
Composición vs. herencia (ejemplo de herencia)
41 |
42 |
43 |
44 |
45 |
48 |
49 | );
50 | }
51 | }
52 |
53 | export default ComponentsWithInheritance;
54 |
--------------------------------------------------------------------------------
/src/sections/conditional.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 |
3 | class LoginButton extends Component {
4 | render () {
5 | return
6 | }
7 | }
8 |
9 | class LogoutButton extends Component {
10 | render () {
11 | return (
12 |
13 |
Bienvenido, usuario!
14 |
15 |
16 | )
17 | }
18 | }
19 |
20 | export default class ConditionalSection extends Component {
21 | constructor() {
22 | super()
23 | this.state = { isUserLogged: false }
24 | }
25 |
26 | render () {
27 | return (
28 |
29 |
Conditional Rendering
30 | {this.state.isUserLogged
31 | ?
32 | :
33 | }
34 |
35 | )
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/sections/events.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 |
3 | export default class Events extends Component {
4 | constructor () {
5 | super()
6 | this.state = { mouseX: 0, mouseY: 0 }
7 | // this.handleMouseMove = this.handleMouseMove.bind(this)
8 | }
9 |
10 | handleMouseMove = (e) => {
11 | const { clientX, clientY } = e
12 | this.setState({ mouseX: clientX, mouseY: clientY })
13 | }
14 |
15 | handleClick (e) {
16 | console.log(e)
17 | console.log(e.nativeEvent)
18 | alert('Hi here!')
19 | }
20 |
21 | render () {
22 | return (
23 |
24 |
Eventos
25 |
26 |
29 |
{this.state.mouseX}, {this.state.mouseY}
30 |
31 |
32 | )
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/sections/fetch-example.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 |
3 | class FetchExample extends Component {
4 | state = { bpi: {}}
5 |
6 | componentDidMount () {
7 | fetch('https://api.coindesk.com/v1/bpi/currentprice.json')
8 | .then(res => res.json())
9 | .then(data => {
10 | const { bpi } = data
11 | this.setState({ bpi })
12 | })
13 | }
14 |
15 | _renderCurrencies () {
16 | const { bpi } = this.state
17 | const currencies = Object.keys(bpi) // ['EUR', 'GBP', 'USD']
18 | return currencies.map(currency => (
19 |
20 | 1 BTC is {bpi[currency].rate}
21 | {currency}
22 |
23 | ))
24 | }
25 |
26 | render () {
27 | return (
28 |
29 |
Bitcoin Price Index
30 | {this._renderCurrencies()}
31 |
32 | )
33 | }
34 | }
35 |
36 | export default FetchExample
37 |
--------------------------------------------------------------------------------
/src/sections/forms.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 |
3 | export default class Forms extends Component {
4 | constructor () {
5 | super()
6 | this.state = {
7 | inputName: '',
8 | inputTwitter: '@',
9 | inputTerms: true
10 | }
11 | }
12 |
13 | handleSubmit = (e) => {
14 | e.preventDefault()
15 | console.log(this.state)
16 | }
17 |
18 | handleChange = (e) => {
19 | console.log('handleChange')
20 | console.log(e.target.checked)
21 | this.setState({ inputTerms: e.target.checked })
22 | }
23 |
24 | render () {
25 | return (
26 |
27 |
Formularios
28 |
62 |
63 | )
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/sections/lists.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import cars from '../data/cars.json'
3 |
4 | class CarItem extends Component {
5 | render () {
6 | const { car, id } = this.props
7 |
8 | return (
9 |
10 | Key: {id}
11 | Nombre: {car.name}
12 | Marca: {car.company}
13 |
14 | )
15 | }
16 | }
17 |
18 | export default class CarsList extends Component {
19 | render () {
20 | return (
21 |
22 | {
23 | cars.map(car => {
24 | return
25 | })
26 | }
27 |
28 | )
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/sections/stateless-proptypes.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import PropTypes from 'prop-types'
3 |
4 | function Article (props) {
5 | return (
6 |
7 | {props.title}
8 | Escrito por {props.author}
9 | {props.date}
10 |
11 | {props.children}
12 |
13 |
14 | )
15 | }
16 |
17 | Article.propTypes = {
18 | title: PropTypes.string.isRequired,
19 | author: PropTypes.string.isRequired,
20 | date: PropTypes.string.isRequired,
21 | children: PropTypes.any
22 | }
23 |
24 | const Button = ({ borderColor = 'red', label }) => (
25 |
28 | )
29 |
30 | Button.propTypes = {
31 | borderColor: PropTypes.string,
32 | label: PropTypes.string.isRequired
33 | }
34 |
35 | class StatelessWithPropTypes extends Component {
36 | render () {
37 | return (
38 |
39 |
Stateless components
40 |
45 | El contenido que envolvemos dentro del componente Article será enviado al componente como this.props.children.
46 | Y mantiene las etiquetas y componentes que hayáis añadido dentro
47 |
48 |
49 |
50 |
51 | )
52 | }
53 | }
54 |
55 | export default StatelessWithPropTypes
56 |
--------------------------------------------------------------------------------