Skip to content

Commit a6bce94

Browse files
authored
Merge pull request #28 from linuxonrails/port_06_movebacktostateless_from_ts_to_js_#15
Port 06 MoveBackToStateless From TS to JS (ES6 >ES6). Issue #15
2 parents 2d538cd + 0a69dd5 commit a6bce94

File tree

8 files changed

+235
-0
lines changed

8 files changed

+235
-0
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"name": "samplereact-es6",
3+
"version": "1.0.0",
4+
"description": "A little project to provide a set of step by step guided samples using React and ES6",
5+
"main": "index.js",
6+
"scripts": {
7+
"start": "webpack-dev-server --inline",
8+
"test": "echo \"Error: no test specified\" && exit 1"
9+
},
10+
"author": "",
11+
"license": "MIT",
12+
"dependencies": {
13+
"bootstrap": "^3.3.7",
14+
"react": "^15.3.2",
15+
"react-dom": "^15.3.2"
16+
},
17+
"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"
29+
},
30+
"repository": {
31+
"type": "git",
32+
"url": "https://github.com/Lemoncode/react-by-sample-es6"
33+
}
34+
}

06 MoveBackToStateless/readme.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# 06 MoveBackToStateless
2+
3+
In example 05 we learned how to remove state from a child control just to have clear governance of state.
4+
5+
It's time to make some cleanup, let's simplify _nameEdit_ component and move it as a stateless component.
6+
7+
We will take a startup point sample _05 MoveBacktOStateless_.
8+
9+
Summary steps:
10+
11+
- Update _nameEdit.jsx_, port it to stateless component and add the methods inline.
12+
13+
14+
## Prerequisites
15+
16+
Install [Node.js and npm](https://nodejs.org/en/) (v6.6.0 or newer) if they are not already installed on your computer.
17+
18+
> Verify that you are running at least node v6.x.x and npm 3.x.x by running `node -v` and `npm -v` in a terminal/console window. Older versions may produce errors.
19+
20+
## Steps to build it
21+
22+
- Copy the content from _05 Refactor_ and execute `npm install`.
23+
24+
- Update _nameEdit.jsx_, port it to stateless component and add the methods inline. It should look like:
25+
26+
```jsx
27+
import React from 'react';
28+
29+
export const NameEditComponent = (props) => {
30+
return (
31+
<div>
32+
<label>Update Name:</label>
33+
<input value={props.editingUserName}
34+
onChange={(e) => props.onEditingNameUpdated(e.target.value)} />
35+
<input type="submit" value="Change" className="btn btn-default"
36+
onClick={props.onNameUpdateRequest} />
37+
</div>
38+
);
39+
}
40+
41+
NameEditComponent.propTypes = {
42+
editingUserName: React.PropTypes.string.isRequired,
43+
onEditingNameUpdated: React.PropTypes.func.isRequired,
44+
onNameUpdateRequest: React.PropTypes.func.isRequired
45+
};
46+
47+
```

06 MoveBackToStateless/src/app.jsx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import React from 'react';
2+
import {HelloComponent} from './hello';
3+
import {NameEditComponent} from './nameEdit';
4+
5+
export class App extends React.Component {
6+
constructor(props) {
7+
super(props);
8+
9+
const defaultUserName = 'defaultUserName';
10+
this.state = {userName: defaultUserName, editingUserName: defaultUserName};
11+
}
12+
13+
setUsernameState() {
14+
this.setState({userName: this.state.editingUserName});
15+
}
16+
17+
updateEditingName(editingName) {
18+
this.setState({editingUserName: editingName});
19+
}
20+
21+
render() {
22+
return (
23+
<div>
24+
<HelloComponent userName={this.state.userName} />
25+
<NameEditComponent
26+
editingUserName={this.state.editingUserName}
27+
onEditingNameUpdated={this.updateEditingName.bind(this)}
28+
onNameUpdateRequest={this.setUsernameState.bind(this)} />
29+
</div>
30+
);
31+
}
32+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import React from 'react';
2+
3+
export const HelloComponent = (props) => {
4+
return (
5+
<h2>Hello user: {props.userName}!</h2>
6+
);
7+
}
8+
9+
HelloComponent.propTypes = {
10+
userName: React.PropTypes.string.isRequired
11+
};
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<title></title>
6+
</head>
7+
<body>
8+
<h1>Sample app</h1>
9+
<div id="root"></div>
10+
</body>
11+
</html>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import React from 'react';
2+
import {render} from 'react-dom';
3+
import {App} from './app';
4+
5+
render(
6+
<App />
7+
, document.getElementById('root'));
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import React from 'react';
2+
3+
export const NameEditComponent = (props) => {
4+
return (
5+
<div>
6+
<label>Update Name:</label>
7+
<input value={props.editingUserName}
8+
onChange={(e) => props.onEditingNameUpdated(e.target.value)} />
9+
<input type="submit" value="Change" className="btn btn-default"
10+
onClick={props.onNameUpdateRequest} />
11+
</div>
12+
);
13+
}
14+
15+
NameEditComponent.propTypes = {
16+
editingUserName: React.PropTypes.string.isRequired,
17+
onEditingNameUpdated: React.PropTypes.func.isRequired,
18+
onNameUpdateRequest: React.PropTypes.func.isRequired
19+
};
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
var path = require('path');
2+
var webpack = require('webpack');
3+
var HtmlWebpackPlugin = require('html-webpack-plugin');
4+
5+
var basePath = __dirname;
6+
7+
module.exports = {
8+
context: path.join(basePath, 'src'),
9+
resolve: {
10+
extensions: ['', '.js', '.jsx']
11+
},
12+
target: 'web',
13+
entry: [
14+
'./main.jsx',
15+
'../node_modules/bootstrap/dist/css/bootstrap.css'
16+
],
17+
output: {
18+
path: path.join(basePath, 'dist'),
19+
filename: 'bundle.js'
20+
},
21+
22+
devtool: 'source-map',
23+
24+
devServer: {
25+
contentBase: './dist', //Content base
26+
inline: true, //Enable watch and live reload
27+
host: 'localhost',
28+
port: 8080,
29+
stats: 'errors-only'
30+
},
31+
32+
module: {
33+
loaders: [
34+
{
35+
test: /\.jsx?$/,
36+
exclude: /node_modules/,
37+
loader: 'babel',
38+
query: {
39+
presets: ['react', 'es2015']
40+
}
41+
},
42+
{
43+
test: /\.css$/,
44+
loader: 'style-loader!css-loader'
45+
},
46+
// Loading glyphicons => https://github.com/gowravshekar/bootstrap-webpack
47+
// Using here url-loader and file-loader
48+
{
49+
test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/,
50+
loader: 'url?limit=10000&mimetype=application/font-woff'
51+
},
52+
{
53+
test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
54+
loader: 'url?limit=10000&mimetype=application/octet-stream'
55+
},
56+
{
57+
test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
58+
loader: 'file'
59+
},
60+
{
61+
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
62+
loader: 'url?limit=10000&mimetype=image/svg+xml'
63+
}
64+
]
65+
},
66+
plugins: [
67+
// Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin
68+
new HtmlWebpackPlugin({
69+
filename: 'index.html', // Name of file in ./dist/
70+
template: 'index.html', // Name of template in ./src
71+
hash: true
72+
})
73+
]
74+
}

0 commit comments

Comments
 (0)