Skip to content

Commit aa7d1bb

Browse files
authored
Merge pull request #51 from HecFranco/master
#50 reviewed and readme_es created
2 parents 19efcbe + 717ea69 commit aa7d1bb

File tree

10 files changed

+332
-149
lines changed

10 files changed

+332
-149
lines changed

05 Refactor/.babelrc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"presets": [
3+
[
4+
"env",
5+
{
6+
"modules": false
7+
}
8+
],
9+
"react"
10+
]
11+
}

05 Refactor/package.json

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,32 @@
11
{
2-
"name": "samplereact-es6",
2+
"name": "sample-es6",
33
"version": "1.0.0",
4-
"description": "A little project to provide a set of step by step guided samples using React and ES6",
4+
"description": "In this sample we are going to setup the basic plumbing to \"build\" our project and launch it in a dev server.",
55
"main": "index.js",
66
"scripts": {
7-
"start": "webpack-dev-server --inline",
7+
"start": "webpack-dev-server --mode development --inline --hot --open",
8+
"build": "webpack --mode development",
89
"test": "echo \"Error: no test specified\" && exit 1"
910
},
1011
"author": "",
11-
"license": "MIT",
12-
"dependencies": {
13-
"bootstrap": "^3.3.7",
14-
"react": "^15.3.2",
15-
"react-dom": "^15.3.2"
16-
},
12+
"license": "ISC",
1713
"devDependencies": {
18-
"babel-core": "^6.18.2",
19-
"babel-loader": "^6.2.7",
20-
"babel-preset-es2015": "^6.18.0",
21-
"babel-preset-react": "^6.16.0",
22-
"css-loader": "^0.25.0",
23-
"file-loader": "^0.9.0",
24-
"html-webpack-plugin": "^2.24.1",
25-
"style-loader": "^0.13.1",
26-
"url-loader": "^0.5.7",
27-
"webpack": "^1.13.3",
28-
"webpack-dev-server": "^1.16.2"
14+
"babel-core": "^6.26.0",
15+
"babel-loader": "^7.1.4",
16+
"babel-preset-env": "^1.6.1",
17+
"babel-preset-react": "^6.24.1",
18+
"css-loader": "^0.28.11",
19+
"file-loader": "^1.1.11",
20+
"html-webpack-plugin": "^3.2.0",
21+
"mini-css-extract-plugin": "^0.4.0",
22+
"url-loader": "^1.0.1",
23+
"webpack": "^4.6.0",
24+
"webpack-cli": "^2.0.14",
25+
"webpack-dev-server": "3.1.0"
2926
},
30-
"repository": {
31-
"type": "git",
32-
"url": "https://github.com/Lemoncode/react-by-sample-es6"
27+
"dependencies": {
28+
"bootstrap": "^4.1.0",
29+
"react": "^16.3.2",
30+
"react-dom": "^16.3.2"
3331
}
3432
}

05 Refactor/readme.md

Lines changed: 75 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,20 @@
11
# 05 Refactor
22

3-
In the previous sample we were setting an initial username value, what would
4-
happen if we expect this value to come from e.g. an AJAX request or if it could
5-
change in time? The current approach won't work.
3+
In the previous sample we were setting an initial username value, what would happen if we expect this value to come from e.g. an AJAX request or if it could change in time? The current approach won't work.
64

75
We can think about two possible solutions:
86

9-
- The first idea that could come into our mind is to implement a mix: we receive via props the current name value, then we hold an state with the current editing
10-
value... what drawbacks could we encounter? We have to listen on the `componentWillReceiveProps` for any change on the parent user name control and replace our state, we end up with a mixed governance.
7+
- The first idea that could come into our mind is to implement a mix: we receive via props the current name value, then we hold an state with the current editing value... what drawbacks could we encounter? We have to listen on the `componentWillReceiveProps` for any change on the parent user name control and replace our state, we end up with a mixed governance.
118

12-
- The second idea is to setup two properties, the parent control will hold _userName_ and _editingUsername_, whenever the user clicks on the button to
13-
replace the name it will notify the parent control and it will replace the
14-
content of _userName_" with the content from _editingUsername_. If _userName_ gets updated by any other third party (e.g. ajax callback) it will update as well
15-
_editingUsername_.
9+
- The second idea is to setup two properties, the parent control will hold _`userName`_ and _`editingUsername`_, whenever the user clicks on the button to replace the name it will notify the parent control and it will replace the content of _`userName`_" with the content from _`editingUsername`_. If _`userName`_ gets updated by any other third party (e.g. ajax callback) it will update as well _`editingUsername`_.
1610

17-
We will take as a starting point sample _04 Callback_:
11+
We will take as a starting point sample _[04 Callback](../04%20Callback/)_:
1812

1913
Summary steps:
2014

21-
- Update _nameEdit.jsx_ in order to request the new _editingUsername_, and remove it from the state.
15+
- Update _[nameEdit.jsx](./src/nameEdit.jsx)_ in order to request the new _`editingUsername`_, and remove it from the state.
2216

23-
- Update _app.jsx_ to hold the new editing property in the state, pass it to the
24-
children, control and perform the proper update on the callback event from the
25-
child control.
17+
- Update _[app.jsx](./src/app.jsx)_ to hold the new editing property in the state, pass it to the children, control and perform the proper update on the callback event from the child control.
2618

2719
## Prerequisites
2820

@@ -32,45 +24,71 @@ Install [Node.js and npm](https://nodejs.org/en/) if they are not already instal
3224
3325
## Steps to build it
3426

35-
- Copy the content from _04 Callback_ and execute `npm install`.
27+
- Copy the content from _[04 Callback](../04%20Callback/)_ and execute `npm install`.
3628

37-
- Update _nameEdit.jsx_ in order to request the new _editingUsername_, and remove it
38-
from the state.
29+
- Update _[nameEdit.jsx](./src/nameEdit.jsx)_ in order to request the new _`editingUsername`_, and remove it from the state.
3930

40-
```jsx
31+
_[nameEdit.jsx](./src/nameEdit.jsx)_
32+
```diff
4133
import React from 'react';
34+
import PropTypes from 'prop-types';
4235

4336
export class NameEditComponent extends React.Component {
4437
constructor(props) {
4538
super(props);
39+
-- this.state = {
40+
-- editingName: this.props.initialUserName,
41+
-- };
42+
43+
-- this.onChange = this.onChange.bind(this);
44+
-- this.onNameSubmit = this.onNameSubmit.bind(this);
4645
}
4746

47+
-- onChange(event) {
48+
-- this.setState({ editingName: event.target.value });
49+
-- }
50+
51+
-- onNameSubmit() {
52+
-- this.props.onNameUpdated(this.state.editingName);
53+
-- }
54+
4855
render() {
4956
return (
5057
<div>
51-
<label>Update Name:</label>
52-
<input value={this.props.editingUserName}
53-
onChange={(e) => this.props.onEditingNameUpdated(e.target.value)} />
54-
<input type="submit" value="Change" className="btn btn-default"
55-
onClick={this.props.onNameUpdateRequest} />
58+
-- <label htmlFor="editingName">Update Name:</label>
59+
++ <label>Update Name:</label>
60+
<input
61+
-- value={this.state.editingName}
62+
++ value={this.props.editingUserName}
63+
-- onChange={this.onChange}
64+
++ onChange={(e) => this.props.onEditingNameUpdated(e.target.value)}
65+
-- id="editingName"
66+
/>
67+
<input
68+
type="submit"
69+
value="Change"
70+
className="btn btn-default"
71+
-- onClick={this.onNameSubmit}
72+
++ onClick={this.props.onNameUpdateRequest}
73+
/>
5674
</div>
5775
);
5876
}
5977
}
6078

6179
NameEditComponent.propTypes = {
62-
editingUserName: React.PropTypes.string.isRequired,
63-
onEditingNameUpdated: React.PropTypes.func.isRequired,
64-
onNameUpdateRequest: React.PropTypes.func.isRequired
80+
-- userName: PropTypes.string.isRequired,
81+
++ editingUserName: PropTypes.string.isRequired,
82+
-- onNameUpdated: PropTypes.func,
83+
++ onEditingNameUpdated: PropTypes.func.isRequired,
84+
++ onNameUpdateRequest: PropTypes.func.isRequired
6585
};
6686
```
6787

68-
- Update _app.jsx_ to hold the new editing property in the state, pass it to the
69-
children control and perform the proper update on the callback event from the
70-
child control.
71-
88+
- Update _[app.jsx](./src/app.jsx)_ to hold the new editing property in the state, pass it to the children control and perform the proper update on the callback event from the child control.
7289

73-
```jsx
90+
_[app.jsx](./src/app.jsx)_
91+
```diff
7492
import React from 'react';
7593
import {HelloComponent} from './hello';
7694
import {NameEditComponent} from './nameEdit';
@@ -79,31 +97,44 @@ export class App extends React.Component {
7997
constructor(props) {
8098
super(props);
8199

82-
const defaultUserName = 'defaultUserName';
83-
this.state = {userName: defaultUserName, editingUserName: defaultUserName};
84-
}
100+
-- this.state = {
101+
-- userName: 'defaultUserName',
102+
-- };
103+
++ const defaultUserName = 'defaultUserName';
85104

86-
setUsernameState() {
87-
this.setState({userName: this.state.editingUserName});
105+
-- this.setUsernameState = this.setUsernameState.bind(this);
106+
++ this.state = {
107+
++ userName: defaultUserName,
108+
++ editingUserName: defaultUserName
109+
++ };
88110
}
89111

90-
updateEditingName(editingName) {
91-
this.setState({editingUserName: editingName});
112+
-- setUsernameState(newName) {
113+
++ setUsernameState() {
114+
this.setState({
115+
-- userName: newName
116+
++ userName: this.state.editingUserName
117+
});
92118
}
93119

120+
++ updateEditingName(editingName) {
121+
++ this.setState({editingUserName: editingName});
122+
++ }
123+
94124
render() {
95125
return (
96126
<div>
97127
<HelloComponent userName={this.state.userName} />
98128
<NameEditComponent
99-
editingUserName={this.state.editingUserName}
100-
onEditingNameUpdated={this.updateEditingName.bind(this)}
101-
onNameUpdateRequest={this.setUsernameState.bind(this)} />
129+
-- initialUserName="Javier Cansado"
130+
-- onNameUpdated={this.setUsernameState}
131+
++ editingUserName={this.state.editingUserName}
132+
++ onEditingNameUpdated={this.updateEditingName.bind(this)}
133+
++ onNameUpdateRequest={this.setUsernameState.bind(this)} />
102134
</div>
103135
);
104136
}
105137
}
106-
```
138+
```
107139

108-
Finally we can check the sample is working as _04 Callback_ executing from the command line
109-
`npm start` and opening [http://localhost:8080](http://localhost:8080).
140+
Finally we can check the sample is working as _[04 Callback](../04%20Callback/)_ executing from the command line `npm start` and opening [http://localhost:8080](http://localhost:8080).

05 Refactor/readme_es.md

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
# 05 Refactor
2+
3+
En la muestra anterior, establecimos un valor de nombre de usuario inicial, ¿qué pasaría si esperamos que este valor provenga de, por ejemplo, una solicitud AJAX o si podría cambiar a tiempo? El enfoque actual no funcionará.
4+
5+
Podemos pensar en dos posibles soluciones:
6+
7+
- La primera idea que nos viene a la mente es implementar una combinación: recibimos a través de _props_ el valor del nombre actual, luego tenemos un _state_ con el valor de edición actual ... ¿qué inconvenientes podríamos encontrar? Tenemos que escuchar en el `componentWillReceiveProps` para cualquier cambio en el control de nombre de usuario principal y reemplazar nuestro estado, terminamos con un gobierno mixto.
8+
9+
- La segunda idea es configurar dos propiedades, el control principal contendrá _`userName`_ y _`editingUsername`_, cada vez que el usuario haga clic en el botón para reemplazar el nombre notificará al control principal y se reemplazará el contenido de _`userName`_ con el contenido de _`editingUsername`_. Si _`userName`_ es actualizado por cualquier otro tercero (por ejemplo, ajax callback) también actualizará _`editingUsername`_.
10+
11+
Tomaremos como punto de partida muestra _[04 Callback](../04%20Callback/)_:
12+
13+
Pasos resumidos:
14+
15+
- Actualice _[nameEdit.jsx](./src/nameEdit.jsx)_ para solicitar el nuevo _`editingUsername`_, y elimínelo del _state_.
16+
17+
- Actualizar _[app.jsx](./src/app.jsx)_ para mantener la nueva propiedad de edición en el estado, pasarla a los elementos secundarios, controlar y realizar la actualización adecuada en el evento de devolución de llamada desde el control secundario.
18+
19+
## Requisitos previos
20+
21+
Instale [Node.js and npm](https://nodejs.org/en/) si aún no están instalados en su computadora.
22+
23+
> Verifique que esté ejecutando al menos los nodos v6.x.x y npm 3.x.x ejecutando `node -v` y` npm -v` en una ventana de terminal / consola. Las versiones anteriores pueden producir errores.
24+
25+
## Pasos para construirlo
26+
27+
- Copie el contenido de _[04 Callback](../04%20Callback/)_ y ejecute `npm install`.
28+
29+
- Actualice _[nameEdit.jsx](./src/nameEdit.jsx)_ para solicitar el nuevo _`editingUsername`_, y elimínelo del estado.
30+
31+
_[nameEdit.jsx](./src/nameEdit.jsx)_
32+
```diff
33+
import React from 'react';
34+
import PropTypes from 'prop-types';
35+
36+
export class NameEditComponent extends React.Component {
37+
constructor(props) {
38+
super(props);
39+
-- this.state = {
40+
-- editingName: this.props.initialUserName,
41+
-- };
42+
43+
-- this.onChange = this.onChange.bind(this);
44+
-- this.onNameSubmit = this.onNameSubmit.bind(this);
45+
}
46+
47+
-- onChange(event) {
48+
-- this.setState({ editingName: event.target.value });
49+
-- }
50+
51+
-- onNameSubmit() {
52+
-- this.props.onNameUpdated(this.state.editingName);
53+
-- }
54+
55+
render() {
56+
return (
57+
<div>
58+
-- <label htmlFor="editingName">Update Name:</label>
59+
++ <label>Update Name:</label>
60+
<input
61+
-- value={this.state.editingName}
62+
++ value={this.props.editingUserName}
63+
-- onChange={this.onChange}
64+
++ onChange={(e) => this.props.onEditingNameUpdated(e.target.value)}
65+
-- id="editingName"
66+
/>
67+
<input
68+
type="submit"
69+
value="Change"
70+
className="btn btn-default"
71+
-- onClick={this.onNameSubmit}
72+
++ onClick={this.props.onNameUpdateRequest}
73+
/>
74+
</div>
75+
);
76+
}
77+
}
78+
79+
NameEditComponent.propTypes = {
80+
-- userName: PropTypes.string.isRequired,
81+
++ editingUserName: PropTypes.string.isRequired,
82+
-- onNameUpdated: PropTypes.func,
83+
++ onEditingNameUpdated: PropTypes.func.isRequired,
84+
++ onNameUpdateRequest: PropTypes.func.isRequired
85+
};
86+
```
87+
88+
- Actualizar _[app.jsx](./src/app.jsx)_ para mantener la nueva propiedad de edición en el estado, pasarla al control secundario y realizar la actualización adecuada en el evento de devolución de llamada desde el control secundario.
89+
90+
_[app.jsx](./src/app.jsx)_
91+
```diff
92+
import React from 'react';
93+
import {HelloComponent} from './hello';
94+
import {NameEditComponent} from './nameEdit';
95+
96+
export class App extends React.Component {
97+
constructor(props) {
98+
super(props);
99+
100+
-- this.state = {
101+
-- userName: 'defaultUserName',
102+
-- };
103+
++ const defaultUserName = 'defaultUserName';
104+
105+
-- this.setUsernameState = this.setUsernameState.bind(this);
106+
++ this.state = {
107+
++ userName: defaultUserName,
108+
++ editingUserName: defaultUserName
109+
++ };
110+
}
111+
112+
-- setUsernameState(newName) {
113+
++ setUsernameState() {
114+
this.setState({
115+
-- userName: newName
116+
++ userName: this.state.editingUserName
117+
});
118+
}
119+
120+
++ updateEditingName(editingName) {
121+
++ this.setState({editingUserName: editingName});
122+
++ }
123+
124+
render() {
125+
return (
126+
<div>
127+
<HelloComponent userName={this.state.userName} />
128+
<NameEditComponent
129+
-- initialUserName="Javier Cansado"
130+
-- onNameUpdated={this.setUsernameState}
131+
++ editingUserName={this.state.editingUserName}
132+
++ onEditingNameUpdated={this.updateEditingName.bind(this)}
133+
++ onNameUpdateRequest={this.setUsernameState.bind(this)} />
134+
</div>
135+
);
136+
}
137+
}
138+
```
139+
140+
Finalmente podemos verificar que la muestra está funcionando como _[04 Devolución de llamada](../04%20Callback/)_ ejecutándose desde la línea de comando `npm start` y abriendo [http://localhost:8080](http://localhost:8080).

0 commit comments

Comments
 (0)