diff --git a/11 TableMock/package.json b/11 TableMock/package.json
index 55a51a6..1e8a276 100644
--- a/11 TableMock/package.json
+++ b/11 TableMock/package.json
@@ -10,22 +10,22 @@
"author": "",
"license": "ISC",
"devDependencies": {
- "babel-core": "^6.18.2",
- "babel-loader": "^6.2.7",
- "babel-plugin-transform-runtime": "^6.15.0",
- "babel-preset-es2015": "^6.18.0",
- "babel-preset-react": "^6.16.0",
- "css-loader": "^0.25.0",
- "file-loader": "^0.9.0",
- "html-webpack-plugin": "^2.24.1",
- "style-loader": "^0.13.1",
- "url-loader": "^0.5.7",
- "webpack": "^1.13.3",
- "webpack-devserver": "0.0.6"
+ "babel-core": "^6.26.0",
+ "babel-loader": "^7.1.4",
+ "babel-preset-env": "^1.6.1",
+ "babel-preset-react": "^6.24.1",
+ "css-loader": "^0.28.11",
+ "file-loader": "^1.1.11",
+ "html-webpack-plugin": "^3.2.0",
+ "mini-css-extract-plugin": "^0.4.0",
+ "url-loader": "^1.0.1",
+ "webpack": "^4.6.0",
+ "webpack-cli": "^2.0.14",
+ "webpack-dev-server": "3.1.0"
},
"dependencies": {
- "bootstrap": "^3.3.7",
- "react": "^15.3.2",
- "react-dom": "^15.3.2"
+ "bootstrap": "^4.1.3",
+ "react": "^16.3.2",
+ "react-dom": "^16.3.2"
}
}
diff --git a/11 TableMock/readme.md b/11 TableMock/readme.md
index 5ea9686..f6af0c9 100644
--- a/11 TableMock/readme.md
+++ b/11 TableMock/readme.md
@@ -9,10 +9,9 @@ We will take a startup point sample _03 State_:
Summary steps:
- Define a model entity (we will call it _member_).
-- Define a fake api (to take thing simple we will just make it synchronous)
+- Define a fake api (to take thing simple we will just make it synchronous).
- We will row component, we will call it _memberRow_.
-- Create a table component, we will call it _memberTable_ and make use of _memberRow
-
+- Create a table component, we will call it _memberTable_ and make use of _memberRow.
## Prerequisites
@@ -24,189 +23,205 @@ Install [Node.js and npm](https://nodejs.org/en/) (v6.6.0 or newer) if they are
- Copy the content from _03 State_ and execute:
- ```
- npm install
- ```
+```
+npm install
+```
+
+- Let's create a model entity in _src/model/member.js_:
-- Let's create some mock data in _src/api/memberMockData.js_:
+```javascript
+class MemberEntity {
+ constructor() {
+ this.id = -1;
+ this.login = '';
+ this.avatar_url = '';
+ }
+}
- ```javascript
- const MembersMockData = [
- {
- id: 1457912,
- login: 'brauliodiez',
- avatar_url: 'https://avatars.githubusercontent.com/u/1457912?v=3',
- },
- {
- id: 4374977,
- login: 'Nasdan',
- avatar_url: 'https://avatars.githubusercontent.com/u/4374977?v=3',
- },
- ];
+export default MemberEntity;
- export default MembersMockData;
+```
- ```
+- Let's create some mock data in _src/api/memberMockData.js_:
+
+```javascript
+const MembersMockData = [
+ {
+ id: 1457912,
+ login: 'brauliodiez',
+ avatar_url: 'https://avatars.githubusercontent.com/u/1457912?v=3',
+ },
+ {
+ id: 4374977,
+ login: 'Nasdan',
+ avatar_url: 'https://avatars.githubusercontent.com/u/4374977?v=3',
+ },
+];
+
+export default MembersMockData;
+
+```
- Define a fake api (to take thing simple we will just make it synchronous) in _src/api/memberAPI.js_:
- ```javascript
- import MembersMockData from './memberMockData';
-
- // Sync mock data API, inspired from:
- // https://gist.github.com/coryhouse/fd6232f95f9d601158e4
- class MemberAPI {
- // This would be performed on the server in a real app. Just stubbing in.
- static _clone(item) {
- return (
- // return cloned copy so that the item is passed by value instead of by reference
- JSON.parse(JSON.stringify(item))
- );
- }
-
- // Just return a copy of the mock data
- getAllMembers() {
- return (
- MemberAPI._clone(MembersMockData)
- );
- }
+```javascript
+import MembersMockData from './memberMockData';
+
+// Sync mock data API, inspired from:
+// https://gist.github.com/coryhouse/fd6232f95f9d601158e4
+class MemberAPI {
+ // This would be performed on the server in a real app. Just stubbing in.
+ static _clone(item) {
+ return (
+ // return cloned copy so that the item is passed by value instead of by reference
+ JSON.parse(JSON.stringify(item))
+ );
}
- const memberAPI = new MemberAPI();
+ // Just return a copy of the mock data
+ getAllMembers() {
+ return (
+ MemberAPI._clone(MembersMockData)
+ );
+ }
+}
- export default memberAPI;
+const memberAPI = new MemberAPI();
- ```
+export default memberAPI;
-- Now it's time jump into the interesting part, let's delete _hello.jsx_ and _nameEdit.jsx_.
-
-- We are going to create an stateless component that will display a single row _memberRow.jsx_.
-
- ```jsx
- import * as React from 'react';
-
- const MemberRow = props => (
-
-
-
- |
-
- {props.member.id}
- |
-
- {props.member.login}
- |
-
- );
-
- MemberRow.propTypes = {
- // Is impossible to use:
- // member: React.PropTypes.instanceOf(MemberEntity),
- // with _clone().
- member: React.PropTypes.shape({
- id: React.PropTypes.number,
- avatar_url: React.PropTypes.string,
- login: React.PropTypes.string,
- }),
- };
-
- export default MemberRow;
+```
- ```
+- Now it's time jump into the interesting part, let's delete _src/hello.jsx_ and _src/nameEdit.jsx_.
+
+- We are going to create an stateless component that will display a single row _src/memberRow.jsx_.
+
+```jsx
+import * as React from 'react';
+import PropTypes from 'prop-types';
+
+const MemberRow = props => (
+
+
+
+ |
+
+ {props.member.id}
+ |
+
+ {props.member.login}
+ |
+
+);
+
+MemberRow.propTypes = {
+ // Is impossible to use:
+ // member: PropTypes.instanceOf(MemberEntity),
+ // with _clone().
+ member: PropTypes.shape({
+ id: PropTypes.number,
+ avatar_url: PropTypes.string,
+ login: PropTypes.string,
+ }),
+};
+
+export default MemberRow;
+
+```
We can't use max-widh in the param style in. We must write 'maxWidth' in the react components.
- Then we are going to implement a component that will display a list of members (and will
- make use of rows), _membersTable.jsx_:
-
- ```jsx
- import * as React from 'react';
- import memberAPI from './api/memberAPI';
- import MemberRow from './memberRow';
-
- class MembersTable extends React.Component {
-
- constructor(props) {
- super(props);
- // set initial state
- this.state = { members: [] };
- }
-
- // Standard react lifecycle function:
- // https://facebook.github.io/react/docs/component-specs.html
- componentWillMount() {
- this.setState({ members: memberAPI.getAllMembers() });
- }
-
- render() {
- return (
-
-
Members Page
-
-
-
- |
- Avatar
- |
-
- Id
- |
-
- Name
- |
-
-
-
- {
- this.state.members.map(member =>
-
- )
- }
-
-
-
- );
- }
+ make use of rows), _src/membersTable.jsx_:
+
+```jsx
+import * as React from 'react';
+import memberAPI from './api/memberAPI';
+import MemberRow from './memberRow';
+
+class MembersTable extends React.Component {
+
+ constructor(props) {
+ super(props);
+ // set initial state
+ this.state = { members: [] };
}
- export default MembersTable;
+ // Standard react lifecycle function:
+ // https://facebook.github.io/react/docs/component-specs.html
+ componentWillMount() {
+ this.setState({ members: memberAPI.getAllMembers() });
+ }
- ```
+ render() {
+ return (
+
+
Members Page
+
+
+
+ |
+ Avatar
+ |
+
+ Id
+ |
+
+ Name
+ |
+
+
+
+ {
+ this.state.members.map(member =>
+
+ )
+ }
+
+
+
+ );
+ }
+}
-- Let's update app.jsx
+export default MembersTable;
- ```jsx
- import React from 'react';
- import MembersTableComponent from './membersTable';
+```
- export class App extends React.Component {
- constructor(props) {
- super(props);
+- Let's update _src/app.jsx_:
- this.state = {
- userName: 'defaultUserName',
- };
+```jsx
+import React from 'react';
+import MembersTableComponent from './membersTable';
- this.setUsernameState = this.setUsernameState.bind(this);
- }
+export class App extends React.Component {
+ constructor(props) {
+ super(props);
- setUsernameState(event) {
- // If the state gets more complex we should use object.assign
- this.setState({
- userName: event.target.value,
- });
- }
+ this.state = {
+ userName: 'defaultUserName',
+ };
- render() {
- return (
-
-
-
- );
- }
- }
+ this.setUsernameState = this.setUsernameState.bind(this);
+ }
- ```
+ setUsernameState(event) {
+ // If the state gets more complex we should use object.assign
+ this.setState({
+ userName: event.target.value,
+ });
+ }
+
+ render() {
+ return (
+
+
+
+ );
+ }
+}
+
+```
- Let's run the sample
diff --git a/11 TableMock/src/app.jsx b/11 TableMock/src/app.jsx
index 4d1ee5b..c5df6ef 100644
--- a/11 TableMock/src/app.jsx
+++ b/11 TableMock/src/app.jsx
@@ -22,7 +22,7 @@ export class App extends React.Component {
render() {
return (
-
+
);
}
diff --git a/11 TableMock/src/memberRow.jsx b/11 TableMock/src/memberRow.jsx
index 31036ac..40fc584 100644
--- a/11 TableMock/src/memberRow.jsx
+++ b/11 TableMock/src/memberRow.jsx
@@ -1,4 +1,5 @@
import * as React from 'react';
+import PropTypes from 'prop-types';
const MemberRow = props => (
@@ -16,12 +17,12 @@ const MemberRow = props => (
MemberRow.propTypes = {
// Is impossible to use:
- // member: React.PropTypes.instanceOf(MemberEntity),
+ // member: PropTypes.instanceOf(MemberEntity),
// with _clone().
- member: React.PropTypes.shape({
- id: React.PropTypes.number,
- avatar_url: React.PropTypes.string,
- login: React.PropTypes.string,
+ member: PropTypes.shape({
+ id: PropTypes.number,
+ avatar_url: PropTypes.string,
+ login: PropTypes.string,
}),
};
diff --git a/11 TableMock/src/membersTable.jsx b/11 TableMock/src/membersTable.jsx
index 0725bef..755ad3c 100644
--- a/11 TableMock/src/membersTable.jsx
+++ b/11 TableMock/src/membersTable.jsx
@@ -18,8 +18,8 @@ class MembersTable extends React.Component {
render() {
return (
-
-
Members Page
+
+
Members Page
diff --git a/11 TableMock/src/model/member.js b/11 TableMock/src/model/member.js
new file mode 100644
index 0000000..3597969
--- /dev/null
+++ b/11 TableMock/src/model/member.js
@@ -0,0 +1,9 @@
+class MemberEntity {
+ constructor() {
+ this.id = -1;
+ this.login = '';
+ this.avatar_url = '';
+ }
+}
+
+export default MemberEntity;
diff --git a/11 TableMock/webpack.config.js b/11 TableMock/webpack.config.js
index f317390..c0c9b9e 100644
--- a/11 TableMock/webpack.config.js
+++ b/11 TableMock/webpack.config.js
@@ -74,6 +74,10 @@ module.exports = {
filename: 'index.html', // Name of file in ./dist/
template: 'index.html', // Name of template in ./src
hash: true
- })
+ }),
+ new MiniCssExtractPlugin({
+ filename: '[name].css',
+ chunkFilename: '[id].css'
+ }),
]
}