Skip to content

Commit 19efcbe

Browse files
authored
Merge pull request #49 from HecFranco/master
#48 reviewed and extended the readme
2 parents b47eeb0 + 2851037 commit 19efcbe

File tree

10 files changed

+375
-197
lines changed

10 files changed

+375
-197
lines changed

04 Callback/.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+
}

04 Callback/package.json

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,32 @@
11
{
2-
"name": "samplereact",
2+
"name": "sample-es6",
33
"version": "1.0.0",
44
"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": "",
1112
"license": "ISC",
1213
"devDependencies": {
13-
"babel-core": "^6.18.2",
14-
"babel-loader": "^6.2.7",
15-
"babel-plugin-transform-runtime": "^6.15.0",
16-
"babel-preset-es2015": "^6.18.0",
17-
"babel-preset-react": "^6.16.0",
18-
"css-loader": "^0.25.0",
19-
"file-loader": "^0.9.0",
20-
"html-webpack-plugin": "^2.24.1",
21-
"style-loader": "^0.13.1",
22-
"url-loader": "^0.5.7",
23-
"webpack": "^1.13.3",
24-
"webpack-devserver": "0.0.6"
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"
2526
},
2627
"dependencies": {
27-
"bootstrap": "^3.3.7",
28-
"react": "^15.3.2",
29-
"react-dom": "^15.3.2"
28+
"bootstrap": "^4.1.0",
29+
"react": "^16.3.2",
30+
"react-dom": "^16.3.2"
3031
}
3132
}

04 Callback/readme.md

Lines changed: 110 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@
22

33
In this sample we are going to refactor the previous sample **03 State**.
44

5-
We'll update the name property only when the user clicks on
6-
a _change_ button, we will simplify the event itself as well.
5+
We'll update the name property only when the user clicks on a _change_ button, we will simplify the event itself as well.
76

8-
Obviously, we will take the sample **03 State** as a starting point.
7+
Obviously, we will take the sample _[03 State](../03%20State/)_ as a starting point.
98

109
Summary steps:
1110

@@ -21,101 +20,130 @@ Install [Node.js and npm](https://nodejs.org/en/) (v6.6.0 or newer) if they are
2120
2221
## Steps to build it
2322

24-
- Copy the content of the `03 State` folder to an empty folder for the sample
25-
and make this your current folder.
23+
- Copy the content of the _[03 State](../03%20State/)_ folder to an empty folder for the sample and make this your current folder.
2624

2725
- Install the npm packages described in the `package.json` and verify that it works:
2826

2927
```bash
3028
npm install
3129
```
3230

33-
- Since we are going to use an internal handler, we'll transform the `NameEditComponent`
34-
from a stateless component into a class component, then we will add some refactor on the naming.
35-
36-
The `nameEdit.jsx` file should looks like this:
37-
38-
```jsx
39-
import * as React from 'react';
40-
41-
export class NameEditComponent extends React.Component {
42-
43-
constructor(props) {
44-
super(props);
45-
// Watch out what would happen if we get this user name via an AJAX callback
46-
// you will find a different implementatin on 05 sample
47-
this.state = {
48-
editingName: this.props.initialUserName,
49-
};
50-
51-
this.onChange = this.onChange.bind(this);
52-
this.onNameSubmit = this.onNameSubmit.bind(this);
53-
}
54-
55-
onChange(event) {
56-
this.setState({ editingName: event.target.value });
57-
}
58-
59-
onNameSubmit() {
60-
this.props.onNameUpdated(this.state.editingName);
61-
}
62-
63-
render() {
64-
return (
65-
<div>
66-
<label htmlFor="editingName">Update Name:</label>
67-
<input value={this.state.editingName} onChange={this.onChange} id="editingName" />
68-
<input type="submit" value="Change" className="btn btn-default" onClick={this.onNameSubmit} />
69-
</div>
70-
);
71-
}
31+
- Since we are going to use an internal handler, we'll transform the `NameEditComponent` from a stateless component into a class component, then we will add some refactor on the naming.
32+
33+
The [nameEdit.jsx](./src/nameEdit.jsx) file should looks like this:
34+
35+
_[nameEdit.jsx](./src/nameEdit.jsx)_
36+
```diff
37+
import React from 'react';
38+
import PropTypes from 'prop-types';
39+
40+
-- export const NameEditComponent = (props) => (
41+
-- <div>
42+
-- <label htmlFor="userName">Update Name:</label>
43+
-- <input id="userName" value={props.userName} onChange={props.onChange} />
44+
-- </div>
45+
-- );
46+
47+
++ export class NameEditComponent extends React.Component {
48+
++ constructor(props) {
49+
++ super(props);
50+
++ // Watch out what would happen if we get this user name via an AJAX callback
51+
++ // you will find a different implementatin on 05 sample
52+
++ this.state = {
53+
++ editingName: this.props.initialUserName,
54+
++ };
55+
56+
++ this.onChange = this.onChange.bind(this);
57+
++ this.onNameSubmit = this.onNameSubmit.bind(this);
58+
++ }
59+
60+
++ onChange(event) {
61+
++ this.setState({ editingName: event.target.value });
62+
++ }
63+
64+
++ onNameSubmit() {
65+
++ this.props.onNameUpdated(this.state.editingName);
66+
++ }
67+
68+
++ render() {
69+
++ return (
70+
++ <div>
71+
++ <label htmlFor="editingName">Update Name:</label>
72+
++ <input value={this.state.editingName} onChange={this.onChange} id="editingName" />
73+
++ <input type="submit" value="Change" className="btn btn-default" onClick={this.onNameSubmit} />
74+
++ </div>
75+
++ );
76+
++ }
77+
++ }
78+
79+
NameEditComponent.propTypes = {
80+
initialUserName: PropTypes.string.isRequired,
81+
-- onChange: PropTypes.func.isRequired,
82+
++ onNameUpdated: PropTypes.func,
83+
};
84+
```
85+
86+
- Let's wire this up in the [app.jsx](./src/app.jsx) file.
87+
88+
_[app.jsx](./src/app.jsx)_
89+
```diff
90+
import React from 'react';
91+
import { HelloComponent } from './hello';
92+
import { NameEditComponent } from './nameEdit';
93+
94+
export class App extends React.Component {
95+
constructor(props) {
96+
super(props);
97+
this.state = {
98+
userName: 'defaultUserName',
99+
};
100+
this.setUsernameState = this.setUsernameState.bind(this);
72101
}
73-
74-
NameEditComponent.propTypes = {
75-
initialUserName: React.PropTypes.string.isRequired,
76-
onNameUpdated: React.PropTypes.func,
77-
};
78-
```
79-
80-
- Let's wire this up in the `app.jsx` file.
81-
82-
```jsx
83-
export class App extends React.Component {
84-
constructor(props) {
85-
super(props);
86-
this.state = { userName: 'defaultUserName' };
87-
this.setUsernameState = this.setUsernameState.bind(this);
88-
}
89-
90-
setUsernameState(newName) {
91-
this.setState({ userName: newName });
92-
}
93-
94-
render() {
95-
return (
96-
<div>
97-
<HelloComponent userName={this.state.userName} />
98-
<NameEditComponent
99-
initialUserName="Javier Cansado"
100-
onNameUpdated={this.setUsernameState}
101-
/>
102-
</div>
103-
);
104-
}
102+
-- setUsernameState(event) {
103+
++ setUsernameState(newName) {
104+
this.setState({
105+
-- userName: event.target.value,
106+
++ userName: newName
107+
});
105108
}
106109

107-
```
110+
render() {
111+
return (
112+
<div>
113+
<HelloComponent userName={this.state.userName} />
114+
<NameEditComponent
115+
-- userName={this.state.userName}
116+
++ initialUserName="Javier Cansado"
117+
-- onChange={this.setUsernameState}
118+
++ onNameUpdated={this.setUsernameState}
119+
/>
120+
a</div>
121+
);
122+
}
123+
}
124+
```
108125

109-
Now we've got a clear event, strongly typed and simplified (straight forward).
126+
Now we've got a clear event, strongly typed and simplified (straight forward).
110127

111128
- Let's give it a try:
112129

113-
```bash
114-
npm start
115-
```
130+
```bash
131+
npm start
132+
```
116133

117134
- Then, load http://localhost:8080/ in a browser to see the output.
118135

119136
![Browser Output](../99_readme_resources/04 Callback/browser_output.png "Browser Output")
120137

121-
Now, the greeting only change when the user clicks on the change button.
138+
Now, the greeting only change when the user clicks on the change button.
139+
140+
## Flow in the Components
141+
142+
* The main component `<App/>` is composed of two subcomponents.
143+
* `<HelloComponent/>`, it receives the state of _userName_ (`userName={this.state.userName}`) with an initial value _'defaultUserName'_, defined in `this.state = { userName: 'defaultUserName' };` inside `<App/>` ( [app.jsx](./src/app.jsx) )
144+
* `<NameEditComponent/>`, it receives a initial value for _Username_ (`initialUserName="Javier Cansado"`) and a method (`onNameUpdated={this.setUsernameState}`) that change the value of _Username_ state `setUsernameState(newName) {
145+
/*...*/}`.
146+
* `<HelloComponent/>`, ( [hello.jsx](./src/hello.jsx) ), show the value received into variable _userName_.
147+
* `<NameEditComponent/>`, ( [nameEdit.jsx](./src/nameEdit.jsx) ), has two methods:
148+
* `onChange(event){}`, changes the 'value' each time it detects a change in the input `<input value={this.state.editingName} onChange={this.onChange} id="editingName" />`.
149+
* `onNameSubmit() {}`, changes the state of _editingName_ that will be uploaded to `<App/>` and giving to `<HelloComponent/>`.

0 commit comments

Comments
 (0)