28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/00 Boilerplate/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "LegacyApps",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "repository": "https://github.com/Lemoncode/integrate-react-legacy-apps.git",
6 | "author": "Santiago Camargo ",
7 | "license": "MIT",
8 | "dependencies": {
9 | "bootstrap": "^3.3.7",
10 | "jquery": "^3.1.1"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/01.A Basic integration/README.md:
--------------------------------------------------------------------------------
1 | # 01 Basic interaction
2 |
3 | In this sample we will introduce our first React component. This component will hold the contacts array in its state and use it to render the table.
4 |
5 | ## Let's get started
6 |
7 | First of all we'll add `react`, `react-dom` and `prop-types` into our app libraries. We manage this with `npm` so we just need to do `npm install` and get this packages.
8 |
9 | ```shell
10 | npm install --save react react-dom prop-types
11 | ```
12 |
13 | Next we'll link these dependencies into our `index.html`:
14 |
15 | ```html
16 | ...
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | ...
26 | ```
27 |
28 | We'll also remove the `table` element and replace it with a div with id *tableComponent* that will contain our React component.
29 |
30 | Then we'll remove`domUtils.js` helper as we only needed it to render the table. We will replace this with our React table component:
31 |
32 | ```html
33 | ...
34 |
35 |
My contacts
36 |
37 |
38 | ...
39 | ```
40 |
41 | After that we will create a namespace called `components` inside our `App.js` to hold our React components, and `PropTypes`, that will hold our properties validation for our components:
42 |
43 | ```javascript
44 | (function initializeApp(window) {
45 | 'use strict';
46 |
47 | var App = {};
48 | App.components = {};
49 | App.PropTypes = {};
50 |
51 | window.App = App;
52 | })(window);
53 | ```
54 |
55 | Let's write our React `TableComponent`, first we'll create a `components` folder inside `app` folder. Then create inside it three files: `ContactsTableComponent.js` that will be our table, `ConctactRowComponent.js`, that will be a reusable row, and `ContactPropTypes.js` that will be the contact typechecking definition for our table components. Our folders tree should look like this:
56 |
57 | ```
58 | .
59 | ├── assets
60 | │ ├── css
61 | │ │ └── styles.css
62 | │ └── js
63 | │ ├── app
64 | │ │ ├── App.js
65 | │ │ ├── components
66 | │ │ │ ├── ContactPropTypes.js
67 | │ │ │ ├── ContactRowComponent.js
68 | │ │ │ └── ContactsTableComponent.js
69 | │ │ ├── modules
70 | │ │ │ └── contactsModule.js
71 | │ │ └── services
72 | │ │ └── contactsService.js
73 | │ └── index.js
74 | └── index.html
75 | ```
76 |
77 | ## Defining our components
78 |
79 | Let's define the validation for contact. This will need two main dependencies, `React` to use its typecheckers, and `App` to export the component so we'll define our component and wrap it in an _IIFE _(Immediately Invoked Function Expression), pass this dependencies and export the definition in `App.PropTypes` subnamespace. Our contact model will have three required attributes, a name as `string`, phone as `number` and `email` as string:
80 |
81 | ```javascript
82 | (function initializeContactPropTypes(React, App) {
83 | 'use strict';
84 |
85 | var ContactPropTypes = PropTypes.shape({
86 | name: PropTypes.string.isRequired,
87 | phone: PropTypes.number.isRequired,
88 | email: PropTypes.string.isRequired
89 | });
90 |
91 | App.PropTypes.ContactPropTypes = ContactPropTypes;
92 | })(window.React, window.App);
93 | ```
94 |
95 | Next let's write the `ContactRowComponent`. We'll wrap it inside an _IIFE_ with React and App as dependencies and create a stateless component using a function that receives a contact inside `props` parameter and returns a row with the contact information:
96 |
97 | ```javascript
98 | (function initializeContactRowComponent(React, App) {
99 | 'use strict';
100 |
101 | var ContactPropTypes = App.PropTypes.ContactPropTypes;
102 |
103 | var ContactRowComponent = function (props) {
104 | var contact = props.contact || {};
105 | return React.createElement('tr', null,
106 | React.createElement('td', null, contact.name),
107 | React.createElement('td', null, contact.phone),
108 | React.createElement('td', null, contact.email)
109 | )
110 | };
111 |
112 | ContactRowComponent.displayName = 'ContactRowComponent';
113 | ContactRowComponent.propTypes = {
114 | contact: ContactPropTypes
115 | };
116 |
117 | App.components.ContactRowComponent = ContactRowComponent;
118 | })(window.React, window.App);
119 | ```
120 |
121 | Then we'll create the `ContactsTableComponent`. It will need a contacts array from props to render the table:
122 |
123 | ```javascript
124 | (function initializeContactsTableComponent(React, App) {
125 | 'use strict';
126 |
127 | var ContactRowComponent = App.components.ContactRowComponent;
128 | var ContactPropTypes = App.PropTypes.ContactPropTypes;
129 |
130 | var ContactsTableComponent = function (props) {
131 | var contacts = props.contacts || [];
132 | return React.createElement(
133 | 'table',
134 | { className: 'table table-stripped table-bordered table-hover' },
135 | React.createElement('thead', null,
136 | React.createElement('tr', null,
137 | React.createElement('th', null, 'Name'),
138 | React.createElement('th', null, 'Phone number'),
139 | React.createElement('th', null, 'Email')
140 | )
141 | ),
142 | React.createElement('tbody', null,
143 | contacts.map(function (contact, index) {
144 | return React.createElement(ContactRowComponent, {
145 | contact: contact,
146 | key: index
147 | });
148 | })
149 | )
150 | );
151 | }
152 |
153 | ContactsTableComponent.displayName = 'ContactsTableComponent';
154 | ContactsTableComponent.propTypes = {
155 | contacts: PropTypes.arrayOf(ContactPropTypes)
156 | };
157 |
158 | App.components.ContactsTableComponent = ContactsTableComponent;
159 | })(React, window.App);
160 | ```
161 |
162 | > As you can see, writing React components using ECMAScript 5 is a little bit verbose and confusing at indentation level because of `React.createElement`. In the next sample we will see how to integrate JSX in our project to enhace the readability of our component and speed the creation process:
163 |
164 | Finally let's include our contacts table files in our `index.html`:
165 |
166 | ```html
167 | ...
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |