├── .gitignore
├── LICENSE
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | IGNORED.md
2 | .idea
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Ahmed Moawad
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | # Easy to go with React
6 | In this tutorial we will talk about how to go through React and prepare you to be able to build web apps using the amazing React like you play with lego bricks :smile:.
7 |
8 |
9 |
10 | ## Table of Contents
11 |
12 | - [Prerequisites](#prerequisites)
13 | - [Tutorial Map](#tutorial-map)
14 | - [Quick Look at ES6](#quick-look-at-es6)
15 | - [let](#let)
16 | - [const](#const)
17 | - [Arrow Functions](#arrow-functions)
18 | - [Default Parameters](#default-parameters)
19 | - [String Interpolation](#string-interpolation)
20 | - [Modules](#modules)
21 | - [React Overview](#react-overview)
22 | - [Setup](#setup)
23 | - [Big Picture](#big-picture)
24 | - [Virtual DOM](#virtual-dom)
25 | - [JSX](#jsx)
26 | - [Intro](#intro)
27 | - [What JSX compiles to](#what-jsx-compiles-to)
28 | - [Expressions](#expressions)
29 | - [HTML Attributes](#html-attributes)
30 | - [Styles](#styles)
31 | - [Binding Events](#binding-events)
32 | - [First Lego](#first-lego)
33 | - [Create it](#create-it)
34 | - [Render it](#render-it)
35 | - [Overview on React Components](#overview-on-react-components)
36 | - [Props](#props)
37 | - [State](#state)
38 | - [Types of Components](#types-of-components)
39 | - [Classical Components](#classical-components)
40 | - [Functional Components](#functional-components)
41 | - [Pure Components](#pure-components)
42 | - [Treating with Forms](#treating-with-forms)
43 | - [Tips and Tricks: Part 1](#tips-and-tricks)
44 | - [Communication between Components](#communication-between-components)
45 | - [From Parent to Child](#from-parent-to-child)
46 | - [From Child to Parent](#from-child-to-parent)
47 | - [Component Life Cycle](#component-life-cycle)
48 | - [constructor](#constructor)
49 | - [componentWillMount](#componentwillmount)
50 | - [render](#render)
51 | - [componentDidMount](#componentdidmount)
52 | - [componentWillReceiveProps](#componentwillreceiveprops)
53 | - [shouldComponentUpdate](#shouldcomponentupdate)
54 | - [componentWillUpdate](#componentwillupdate)
55 | - [componentDidUpdate](#componentdidupdate)
56 | - [componentWillUnmount](#componentwillunmount)
57 | - [Type checking with PropTypes](#type-checking-with-proptypes)
58 | - [Practice React](#practice-react)
59 | - [Final Words](#final-words)
60 | - [To Be Added](#to-be-added)
61 | - [Author](#author)
62 | - [Contribution](#contribution)
63 | - [Support Us](#support-us)
64 |
65 |
66 |
67 | ## Prerequisites
68 | In order to go ahead with this tutorial, You should have good knowledge about the following
69 |
70 | - [HTML](https://developer.mozilla.org/en-US/docs/Web/HTML)
71 | - [CSS](https://developer.mozilla.org/en-US/docs/Web/CSS)
72 | - [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript)
73 |
74 |
75 | ## Tutorial Map
76 | 
77 |
78 |
79 | ## Quick Look at ES6
80 | > We will take here a quick tour on the new features on EchmaScript 6.
81 |
82 | ### let
83 | We all know that declaring variable with `var` makes this variable available only on the function scope that it has been declared in. But with `let` every `{ }` consider a scope so any variable that declared with `let` will available only on this curly braces scope.
84 |
85 | > Example using `var`:
86 | ```javascript
87 | if (true) {
88 | var x = 5
89 | }
90 | console.log("using var: ", x)
91 | ```
92 | it will result: ` using var: 5 `
93 |
94 | > Example using `let`:
95 | ```javascript
96 | if (true) {
97 | let x = 5
98 | }
99 | console.log("using let: ", x)
100 | ```
101 | it will result: `ReferenceError: x is not defined`
102 |
103 | So `let` make a scope within `if` statement curly braces and `var` don't.
104 |
105 | ### const
106 | `const` almost used to daclare any variables that will not changed or in accurate say you will not assign it a new value using `=` because when you declare a composite typed variable like objects or arrays you can add or remove elements to or from it normally but you can't asign to the variable another value.
107 |
108 | ```javascript
109 | const x = [1, 2, 3]
110 | x.push(4) // x will now be [1, 2, 3, 4]
111 | // but
112 | x = [1, 4, 6] // It will raise TypeError: Assignment to constant variable
113 | ```
114 |
115 | ### Arrow Functions
116 | Arrow Functions is a special type of functions that solve the problem of `this` keyword strange behavior when calling function from a context other than its own one ( it's not strange if you know how it works :smile: ) and convert it to Lexical `this` so that it maintains that the context that call it will be the reference `this`.
117 |
118 | Examples on How to write it:
119 | ```javascript
120 | // Shorthand arrow functions with returned expression
121 | const expressionFn = (x, y) => x + y;
122 |
123 | // Statement Arrow Functions
124 | const statementFn = (x, y) => {
125 | if (x && y) {
126 | return x + y
127 | }
128 | return false
129 | }
130 | ```
131 |
132 | ### Default Parameters
133 | EcmaScript6 added the ability to add default values to the given parameters if it's not be provided to the function. And that's for sure make the code more readable and organizable.
134 |
135 | Here is an example
136 | ```javascript
137 | function doSum (x, y = 7, z = 12) {
138 | return x + y + z;
139 | }
140 |
141 | doSum(2) // output: 21
142 | doSum(2,4) // output: 18
143 | doSum(2,4,10) // output: 16
144 | ```
145 | > Note: You must make function default parameters the last parameters of it in arrangement or assign its value to `undefined` when calling the function but that will be little confusing
146 | ```javascript
147 | function doSum (x, y = 7, z) {
148 | return x + y + z;
149 | }
150 |
151 | doSum(2,undefined,6) // output will be 2 + 7 + 6 = 15
152 | ```
153 |
154 | ### String Interpolation
155 | String Interpolation give the ability to write more readable and organized strings without need to use `+` operator to concatenate the string typed variables with each other.
156 |
157 | Here is an example for that
158 |
159 | ```javascript
160 | const firstName = 'Ahmed'
161 |
162 | const lastName = 'Moawad'
163 |
164 | let fullName = 'Full Name is ' + firstName + ' ' + lastName // The old way
165 |
166 | fullName = `Full Name is ${firstName} ${lastName}` // New String Interpolation
167 |
168 | // Result for both: Full Name is Ahmed Moawad
169 | ```
170 |
171 | ### Modules
172 | This is a big new feature and all JavaScript was waiting for releasing it to make your code more modular and organized. There is three points that we will talk about for this feature:
173 |
174 | #### 1. Exporting
175 | > In order to make class, function or any variable inside a file (module) available in other files (modules) we use module exporting, and here are some examples for how to do that:
176 |
177 | ```javascript
178 | /**
179 | * @file index.js
180 | */
181 |
182 | // Exporting Function
183 | export function getFullName(firstName, lastName) {
184 | return `${firstName} ${lastName}`
185 | }
186 |
187 | // Exporting variable
188 | export const title = "Frontend Engineer"
189 |
190 | ```
191 |
192 | #### 2. Importing
193 | > In order to import class, function or any type of variable inside a file (module) to be able to use it in this file we use module importing, and here are some examples for how to do that:
194 |
195 | ```javascript
196 | /**
197 | * @file about.js
198 | */
199 |
200 | // Import getFullName function and title variable from index module
201 | import { getFullName, title } from 'index'
202 |
203 | // Use them
204 | const fullName = getFullName('Ahmed', 'Moawad')
205 |
206 | console.log(`My Name is ${fullName} and I'm ${title}`)
207 |
208 | // Result: My Name is Ahmed Moawad and I'm Frontend Engineer
209 |
210 | ```
211 |
212 | #### 3. Default Exporting
213 | > This is an awesome feature in order to make any kind of variables the default one when exporting to other modules. Here is an example that will explain it's functionality in more details:
214 |
215 | ```javascript
216 | /**
217 | * @file index.js
218 | */
219 |
220 | /*
221 | * .... brevious code
222 | */
223 |
224 | // Export the following Object as the default export for index module
225 | export default {
226 | firstName: 'Ahmed',
227 | lastName: 'Moawad',
228 | title: 'Frontend Engineer'
229 | }
230 |
231 |
232 | /**
233 | * @file about.js
234 | */
235 |
236 | // Import Default without the curly braces and with any name you choose for it
237 | import myData, { getFullName } from index
238 |
239 | const fullName = getFullName(myData.firstName, myData.lastName)
240 |
241 | console.log(`My Name is ${fullName} and I'm ${myData.title}`)
242 |
243 | // Result: My Name is Ahmed Moawad and I'm Frontend Engineer
244 |
245 | ```
246 |
247 |
248 | ## React Overview
249 | In this section we will talk about React and why using it over other like libraries.
250 |
251 | > If you don't need from me to prove to you that React is amazing :smile: you can just move to [Big Picture](#big-picture) section directly.
252 |
253 | ### What is React
254 | > Source of following definition is from [React official website](https://reactjs.org/tutorial/tutorial.html#what-is-react)
255 |
256 | React is a declarative, efficient, and flexible JavaScript library for building user interfaces.
257 |
258 | ### So Why React?
259 | Of course, there are many reasons to use React but I will write down some of them:
260 |
261 | #### 1. React is a component based Libray
262 | That's mean with React you can produce reusable isolated elements called components that reduce the redundancy of your application elements, improve code quality and inspire collaboration with it's community.
263 |
264 | #### 2. React is Fast
265 | React uses [Virtual Dom](#virtual-dom) mechanism to improve the application rendering performance and reduce the unnecessary rendering and modification So your application will be very healthy and efficient.
266 |
267 | #### 3. React has a single source of truth
268 | React adopt the concept of unidirectional Data Binding. So it removes the ambiguity of conflicts results from the existance of different sources of the data.
269 |
270 | #### 4. React has a full support to [Redux](https://redux.js.org)
271 | So You can manage your application state with the awesome Redux.
272 |
273 | #### 5. React has a growing EcoSystem
274 | Facebook and React community developed React and it's ecosystem rapidly. You can find [ReactNative](https://facebook.github.io/react-native/) for mobile development, [ReactRouter](https://reacttraining.com/react-router/) for client and server rendering, [Redux](https://redux.js.org) integration for managing your Application State, [Jest](https://facebook.github.io/jest/) and [Enzyme](http://airbnb.io/enzyme)for testing your React Applications and many others.
275 |
276 | #### 6. React has awesome DevTools
277 | React has it's official [DevTools](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en) to enhance the way you debug your React application.
278 |
279 | #### 7. React scale from small to Big applications
280 | React give you the ability to produce small scale appication and can easily scale to a large web applications.
281 |
282 | > There are many other reasons to develop with React. I hope you touch them while developing with React
283 |
284 |
285 | ## Setup
286 |
287 | We will use in this tutorial the simple and easy method to create react app called `create-react-app` package
288 | 1. Install `create-react-app` NPM package globally
289 | ```
290 | npm i -g create-react-app
291 | ```
292 | 2. Create your app
293 | ```
294 | create-react-app your-project-name
295 |
296 | cd your-project-name
297 |
298 | yarn install
299 | ```
300 | 3. Start your app
301 | ```
302 | yarn start
303 | ```
304 |
305 | You can visit [Create React App](https://github.com/facebookincubator/create-react-app) for more info.
306 |
307 |
308 | ## Big Picture
309 |
310 |
311 |
312 |
313 | -- Illustrative Example explains React Components in a simple way --
314 |
315 |
316 |
317 |
318 |
319 | React is component based library so Component is considered the core unit of React.
320 |
321 | As we have seen in the illustrative example, The component is consists of some props that will be provided to it at its construction and have a state that is represents the behaviour of the component and will be initialized during component construction.
322 |
323 | After Construction Your component Layout (HTML Template) will be rendered based on the provided props and the initialized State.
324 |
325 | And If the component be provided by different props or the state of it changes, The component will be rendered another time with the new effect.
326 |
327 | The component have a life cycle we will talk about it later in details to show how to use it the best way.
328 |
329 |
330 |
331 | ## Virtual DOM
332 | > React uses Virtual DOM in order to enhance the web application performance, So React is very fast.
333 |
334 | ### Problem to Be solved
335 | Manipulating with the DOM is slow because changing it directly change the web page. So If you changed it many times you will suffer from rendering performance issue and nowadays Most of Web Apps needs to change the DOM frequently. So Virtual DOM came to solve this problem.
336 |
337 | ### What is Virtual DOM
338 | > Source of following definition is [Codecademy](https://www.codecademy.com/articles/react-virtual-dom)
339 |
340 | A virtual DOM object is a representation of a DOM object, like a lightweight copy.
341 |
342 | A virtual DOM object has the same properties as a real DOM object, but it lacks the real thing's power to directly change what's on the screen.
343 |
344 | Manipulating the DOM is slow. Manipulating the virtual DOM is much faster, because nothing gets drawn onscreen. So React updates all DOM changes on the virtual DOM then at the end it will compare the `actual DOM` with the `virtual DOM` and only redraw the affected components by these changes.
345 |
346 | Think of manipulating the virtual DOM as editing a blueprint, as opposed to moving rooms in an actual house.
347 |
348 |
349 |
350 | ## JSX
351 | > It’s not a new language, but it is awesome
352 |
353 | ### Intro
354 | Look at the following Code
355 |
356 | ```jsx
357 | const element =
Hello, React lovers!
;
358 | ```
359 |
360 | What is that Code?
361 |
362 |
363 | It's neither HTML nor JavaScript. It just the awesome JSX.
364 |
365 |
366 | ### What JSX compiles to
367 | > We use JSX to transpile it to vanilla JavaScript using [Babel](https://babeljs.io/)
368 |
369 | The following code is JSX:
370 | ```jsx
371 | const element =
Hello, React Lovers!
;
372 | ```
373 | will be compiled using [Babel](https://babeljs.io/) to the following Code:
374 |
375 | ```javascript
376 | // Create a React Element
377 | const element = React.createElement(
378 | 'h1' , // The Tag Name of the element
379 | {className: 'greet'} , // The properties of this element
380 | ‘Hello, React Lovers!’ // HTML Content inside the Element
381 | )
382 | ```
383 | and React now will take it's responsibility to convert that to HTML DOM Element as follows:
384 |
385 | ```html
386 |
Hello, React Lovers!
387 | ```
388 | Now, We will take a quick tour on How to write JSX in order to write React web apps
389 |
390 | ### Expressions
391 | Now we will introduce how treat with JavaScript Expressions and how to interpolate them in JSX templates in order to generate dynamic components.
392 |
393 | ```jsx
394 | var name = 'Ahmed'
395 | //Interpolation in JSX
396 | var element =
Hello, { name }
;
397 |
398 | //Use JSX as an Expression
399 | function sayHello(name){
400 | if(name)
401 | return
Hello, { name }
;
402 | return
Hello, Guest
;
403 | }
404 | ```
405 |
406 | So the generated HTML based on the above parameters will be:
407 |
408 | ```html
409 |
Hello, Ahmed
410 | ```
411 |
412 | ### HTML Attributes
413 | Now let's talk about how to provide the elements with the HTML attributes
414 |
415 | > Note: JSX use JavaScript Syntax (camelCase) not HTML Syntax in adding attributes i.e
416 |
417 | There are the list of HTML attributes that you can use in JSX:
418 |
419 | ```
420 | accept acceptCharset accessKey action allowFullScreen allowTransparency alt async
421 | autoComplete autoFocus autoPlay capture cellPadding cellSpacing challenge charSet
422 | checked cite classID className colSpan cols content contentEditable contextMenu
423 | controls controlsList coords crossOrigin data dateTime default defer dir disabled
424 | download draggable encType form formAction formEncType formMethod formNoValidate
425 | formTarget frameBorder headers height hidden high href hrefLang htmlFor httpEquiv
426 | icon id inputMode integrity is keyParams keyType kind label lang list loop low
427 | manifest marginHeight marginWidth max maxLength media mediaGroup method min
428 | minLength multiple muted name noValidate nonce open optimum pattern placeholder
429 | poster preload profile radioGroup readOnly rel required reversed role rowSpan
430 | rows sandbox scope scoped scrolling seamless selected shape size sizes span
431 | spellCheck src srcDoc srcLang srcSet start step style summary tabIndex target
432 | title type useMap value width wmode wrap
433 | ```
434 |
435 | You can notice that class HTML attribute has been renamed with `className` in order to doesn't make a conflict with `class` keyword in JavaScript. and Html label attribute for converted to `htmlFor` too.
436 |
437 | Here an Example:
438 | ```jsx
439 | var cls = 'greet';
440 | var element =
Hello, { name }
;
441 |
442 | ```
443 |
444 | ### Styles
445 |
446 | You can add inline styles to your element using the follwing method
447 |
448 | ```jsx
449 | // Construct a Style Object
450 | var styles = {
451 | backgroundColor: 'red', // the style properties follows JavaScript naming convention
452 | color : 'orange'
453 | }
454 |
455 | var element =
Hello There
;
456 |
457 | ```
458 |
459 | ### Binding Events
460 | Now, Let's talk about how to bind events to the element, we will use this naming covention:
461 |
462 | For Example, Click Event will be `onClick` instead of `onclick`.
463 |
464 | Here are some examples for doing that
465 |
466 | ```jsx
467 | // Add Input event using anonymous function
468 | let input = (e.target.value)}/>;
469 |
470 | // Add Click Event use predifned function called someFn
471 | let button = ;
472 |
473 | var v;
474 | let select= ();
479 | ```
480 |
481 |
482 | ## First Lego
483 | > I mean First React Component :wink:
484 | As we have seen in [Big Picture](#big-picture) section that the component is the main component and here we will create it and then rendered it.
485 |
486 | Let first setup our application using the instructions in [Setup](#setup) section.
487 |
488 | Then Create a file called `Hello.js` in `src` directory. So the hierarchy will be something like that:
489 | ```
490 | Your-App-Name
491 | |
492 | - public
493 | | |
494 | | - index.html
495 | |
496 | - src
497 | | |
498 | | - index.js
499 | | - Hello.js
500 | ```
501 |
502 | ### Create it
503 | Here is an example of how to create new Component in the created file `Hello.jsx`
504 | ```jsx
505 | /**
506 | * @file Hello.js
507 | */
508 |
509 | // import React
510 | import React from 'react';
511 |
512 | // Create Hello Component
513 | class Hello extends React.Component {
514 | /**
515 | * Render Function is responsible for render this component
516 | */
517 | render() {
518 | return
Hello, {this.props.name}
;
519 | }
520 | }
521 | ```
522 |
523 |
524 |
525 |
526 | ### Render it
527 | Now, Let's render it on our application. Open file called `index.js` and use your component inside it like the following
528 |
529 | ```js
530 | /**
531 | * @file index.js
532 | */
533 |
534 | // Import React DOM - It responsible for compiling React Component into HTML Element
535 | import ReactDOM from 'react-dom';
536 |
537 | // Import Your Component
538 | import Hello from 'Hello';
539 |
540 | // Run the Render Function to render your App
541 | ReactDOM.render(
542 | , // Use your component and provide it with name prop
543 | document.getElementById('root') // Render your App into the element whose id named root
544 | );
545 |
546 | ```
547 |
548 | What happens above is that we use ReactDOM method called `render` to render your application into the static html file called `index.html`.
549 |
550 |
551 |
552 |
553 |
554 | Now run this command: `yarn start`
555 |
556 | Congratulations :tada:! you just created your first React Component Keep the good spirit on :muscle:.
557 |
558 |
559 |
560 | ## Overview on React Components
561 | > I mean Lego bricks :confused:
562 |
563 | Components let you split the UI into independent, reusable pieces, and think about each piece in isolation.
564 |
565 | We will talk now in details about the [props](#props) (Inputs) and the [state](#state) of the component.
566 |
567 | Later when we will be familiar with React, will discuss the component [Life Cycle](#life-cycle)
568 |
569 | ### Props
570 | > Props regarding to the component are like Eye Color regarding to you, I hope you don’t put lenses
571 |
572 | Component haven't any responsiblity on creating or updating the `props` it uses it only to generate it's `state` and it's HTML Template UI.
573 |
574 | You can think of `props` like weather temperature (Something you have no hand on changing it), If the temperature goes down, We put on more clothes and vice versa.
575 |
576 | > Note: All React components must act like pure functions with respect to their props.
577 |
578 | #### Use it
579 | Here is an example on How to use props on component
580 |
581 | ```jsx
582 | /**
583 | * @file Hello.js
584 | */
585 |
586 | /* ... */
587 | class Hello extends React.Component {
588 | render() {
589 | return
590 |
591 | Hello, I'm {this.props.name}
592 |
;
593 | }
594 | }
595 |
596 | ```
597 |
598 | ```jsx
599 | /**
600 | * @file index.js
601 | */
602 |
603 | /* ... */
604 | ReactDOM.render(
605 | ,
606 | document.getElementById('root')
607 | );
608 |
609 | ```
610 | And the result will be something like that
611 |
612 |
613 |
614 | Hello, I'm Ahmed
615 |
616 |
617 | ### State
618 | > State regarding to the component are like your mood regarding to you, I hope you’re happy
619 |
620 | React Component have the full control of it's state. It can initialize, use and update it.
621 |
622 | You can think of `state` like your mood based on the weather. Some of us feel happy when it's raining, but some others feel bored.
623 |
624 | So The weather temperature will be like a `prop` and your mood that depending on the weather will be like `state`.
625 |
626 | Let's know How to manage the component state.
627 |
628 | #### Initialize and use it
629 |
630 | We can initialize the state of the component in the `constructor` method of the component `class`
631 |
632 | ```jsx
633 | /**
634 | * @file Hello.js
635 | */
636 |
637 | /* ... */
638 | class Hello extends React.Component {
639 | constructor(props) {
640 | // we must call super method at the first in order to define the class as React component
641 | super(props)
642 |
643 | // we can initialize the state like the following
644 | this.state = {mood: 'happy'}
645 | }
646 |
647 | render() {
648 | return (
649 |
650 | Hello, {this.props.name}
651 |
);
652 | }
653 | }
654 | ```
655 |
656 | and the result will be something like that:
657 |
658 |
659 | :grinning: Hello, I'm Ahmed
660 |
661 |
662 | #### Change it
663 |
664 | We can update the state using `setState`. Let's take an example
665 |
666 | ```jsx
667 | class Hello extends React.Component {
668 | constructor(props) {
669 | /* ... */
670 |
671 | // Add interval to change the mood every 0.5 sec
672 | window.setInterval(this.toggleMood, 500)
673 | }
674 |
675 | toggleMood () {
676 | let currentMood = (this.state.mood === ‘happy’)? ‘sad’ : ‘happy’;
677 | this.setState({mood: currentMood});
678 | }
679 |
680 | render() {
681 | return(
682 | Hello, {this.props.name}
683 |
684 |
);
685 | }
686 | }
687 | ```
688 |
689 | The result will be something like that
690 |
691 |
692 |
693 | Hello, I'm Ahmed
694 |
695 |
696 |
697 |
698 | ## Types of Components
699 | There are three main types of components and everyone of them has a use case in order to improve code quality and app performance. So we will display them on the following sections:
700 |
701 | ### Classical Components
702 | > Classical means that the component is a class (If you work without the sugar of es6 the component will be factory method).
703 |
704 | This is the default type of component that gives you ability to:
705 | - Initialize and Use the `state`
706 | - Add Implementation for [Life Cycle](#component-life-cycle) hook methods.
707 |
708 | > Example:
709 |
710 | ```jsx
711 | class Comp extends React.Component {
712 | constructor(props) {
713 | super(props);
714 | // initialize the state here
715 | this.state = {value: ''};
716 |
717 | }
718 |
719 | render() {
720 | return
{this.state.value}
;
721 | }
722 |
723 | componentWillMount (e) {
724 | // Implement life cycle hook if you want
725 | }
726 | }
727 |
728 | ```
729 |
730 | So if your component is as simple as getting props and renders component template based on it only, you can use the [Functional Components](#functional-components) instead.
731 |
732 | ### Functional Components
733 | > We can call them stateless components too.
734 |
735 | These component are a pure functions that take `props` as input and return an HTML Template based on it. So it's called stateless components because they don't use state.
736 |
737 | The whole component will act like `render` method in [classical components](#classical-components).
738 |
739 | > For Example:
740 |
741 | ```jsx
742 | const SimpleComp = (props) => {
743 | return
744 |
{props.name}
745 |
{props.about}
746 |
;
747 | }
748 | ```
749 |
750 | > Note that `props` here is an function argument so we don't use `this`.
751 |
752 | ### Pure Components
753 | Pure Component are used in order to boost the app performance and don't make unnecessary rendering while the next `state` and `props` are the same as the previous ones.
754 |
755 | So Pure Components are the same as [classical components](classical-components) but it only shallowed [`shouldComponentUpdate`](#shouldcomponentupdate) method and make it doesn't return true if the `props` and `state` didn't change while updating.
756 |
757 | > Example:
758 |
759 | ```jsx
760 | class PureComp extends React.PureComponent {
761 | constructor(props) { /* ... */}
762 |
763 | render() {
764 | return
{this.state.value}
;
765 | }
766 | }
767 |
768 | ```
769 |
770 | > Note: Use `PureComponent` only if your `props` and `state` are haven't complex data structures. If them are consists of pure or immutable data types it will works fine otherwise it will fail.
771 |
772 |
773 |
774 | ## Treating with Forms
775 | > In React, We doesn’t treat forms as like classic way
776 |
777 | ### Overview
778 |
779 |
780 |
781 |
782 | Submitting Form doesn’t mean reloading the web page because that's not the react way and herrewe treat with a single page application.
783 |
784 | Form Component State are the source of truth for the form values so when we proceed to submit the form we get it's values from the state of it's React component in order to maintain the unidirectional data flow mechanism.
785 |
786 | ### Implement It
787 | Here are an example of how to create a form and manage it's submittion.
788 |
789 | ```jsx
790 | class CustomForm extends React.Component {
791 | constructor(props) {
792 | super(props);
793 |
794 | // initialize the form values state here
795 | this.state = {value: ''};
796 |
797 | // bind all prototype methods to the component context - we will discuss this issue below
798 | this.handleSubmit = this.handleSubmit.bind(this)
799 | this.handleChange = this.handleChange.bind(this)
800 |
801 | }
802 |
803 | render() {
804 | return ;
808 | }
809 |
810 | handleChange (e) {
811 | // update the state based on the changing input value
812 | this.setState({value: e.target.value})
813 | }
814 |
815 | handleSubmit (e) {
816 | e.preventDefault()
817 | /*
818 | * We have now all the form values stored on the component state,
819 | * So we can make an ajax request or validate the date before that,
820 | * or do whatever your business required
821 | */
822 | }
823 | }
824 |
825 | ```
826 |
827 | Now let's discuss what we have done with the above Form Component in many points:
828 |
829 | 1. If we want to have a controlled Component, we must map every form input values to a state property as we have done above.
830 |
831 | 2. We notice that we use `bind` method to bind `handleSubmit` and `handleChange` methods to the component context. That's because when we use it in the jsx template these methods loses the context of the component so if we didn't bind them like that then if we use `this` keyword in these methods it will not refer to any context so must bind it hardly to the context that we want in order to everything go as we have planned.
832 |
833 | 3. We notice that we bind the input value attribute to the state property `value` so the value of this component came from one source of truth (The state) and then we handle `change` event on the input to get the value that came from the user and update the state with it so the bound input value will be changed by changing the state.
834 |
835 | 4. In `handleChange` we can validate the coming value before updating the state with in order to grauntee that the values that will be submitted is correct.
836 |
837 | 5. In `handleSubmit` we prevent the default behaviour from happening, and then we can use the state as the source of the form values that we will submit.
838 |
839 | ## Tips and Tricks
840 |
841 | ### Use the magic of `&&`
842 | > Let's explain firstly how `&&` works
843 |
844 | `&&` operator seeks for the falsy value of the two operands. And it will stop seeking when it finds any falsy and return the last value it stops at. Here are some examples of it
845 |
846 | > Note: Falsy values in JavaScript are (`false`, `0`, `NaN`, `''`, `undefined`, `null`)
847 |
848 | ```javascript
849 | 4 && 0 // return 0
850 | '' && 'React' // return ''
851 | true && 5 // return 5 (not true)
852 | ```
853 |
854 | now let's show how to use it in React:
855 |
856 | ```jsx
857 | class Visit extends React.Component {
858 | render() {
859 | return
860 | { this.props.visits > 0 &&
You have {this.props.visits} visits
}
861 |
;
862 | }
863 | }
864 |
865 |
866 | ReactDOM.render( , document.getElementById('root'));
867 |
868 | ```
869 | When rendering this compoenent it will show the following
870 |
871 |
You have 6 visits
872 |
873 |
874 | That's because the `visits` prop is `6` that is greater than `0` so the first expression will return `true` So `&&` will continue seeking for the falsy value so it returns the second operand which is the element that we want to render if the `visits` prop is greater than `0`.
875 |
876 | ### Use the `map` function
877 |
878 | Map function is one of the JavaScript Array's methods that use an array to produce another array based on the first one. Here is an example of it.
879 |
880 | And You can read about it in [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)
881 |
882 | ```javascript
883 |
884 | let arr = ['A', 'M', 'Z']
885 |
886 | // Now let generate an array of char code based on the previous array
887 | let codeArr = arr.map(ch => ch.charCodeAt(0)) // codeArr will be [65, 77, 90]
888 | ```
889 |
890 | Now let's use it to generate alist of elements in React:
891 | ```jsx
892 |
893 | class NameList extends React.Component {
894 | render() {
895 | return
896 | {this.props.users.map( user =>
{ user }
)}
897 |
;
898 | }
899 | }
900 |
901 | ReactDOM.render( , document.getElementById('root'));
902 |
903 | ```
904 | Now the result will be something like the following:
905 |
906 |
907 |
Ahmed
908 |
Ali
909 |
Sara
910 |
911 |
912 |
913 | ## Communication between Components
914 |
915 |
916 |
917 |
918 |
919 | The above illustration explains how components communicate with each others.
920 |
921 | let's devide the communication between components into two types based on their position:
922 |
923 | ### From Parent to Child
924 | This is the tradional way of communication because the Parent component is responsible for providing the props to it's children So when parent want to communicate with child it provide it with props.
925 |
926 | > Here is an example of that:
927 |
928 | ```jsx
929 | // Build Child Component
930 | class Child extends React.Component {
931 | render() {
932 | return
;
952 | }
953 | }
954 |
955 | ```
956 |
957 | So We see here that Child prop `name` is depending on the Parent `name` state property.
958 |
959 | ### From Child to Parent
960 | Another way of communication is when child want to notify the parent about something change in it. So In React we use callback Invoking that's mean that the parent provide the component with callback prop that will be invoked on the right time to change something in Parent Component.
961 |
962 | > Let's take an Example
963 |
964 | ```jsx
965 | class Parent extends React.Component {
966 | /* ... */
967 | render() {
968 | return
969 |
{this.state.value}
970 | {/* we can provide the callback as prop like onChange prop*/}
971 |
972 |
;
989 | }
990 |
991 | handleInputChange(e){
992 | // Here we use onChange Prop to invoke the parent handleChange Method
993 | this.props.onChange(e.target.value)
994 | }
995 | }
996 |
997 | ```
998 |
999 | As we have seen above in child component if the user change the input `handleInputChange` will be invoked. And when `handleInputChange` have invoked it will invoke the provided method prop `onChange` and pass it the required parameter that will change the state of parent.
1000 |
1001 |
1002 |
1003 | ## Component Life Cycle
1004 | > And Component Said: Yes, I have my own life. Deal with it
1005 |
1006 | Life Cycle is a way to hook the Component life phases to do the right action on the right time
1007 |
1008 | Component Have three main life phases:
1009 |
1010 | #### :triangular_flag_on_post: Mounting Phase
1011 |
1012 | This is the phase where the component been constructed, initialized and rendered for the first time on the DOM.
1013 |
1014 |
1015 |
1016 |
1017 |
1018 |
1019 | #### :triangular_flag_on_post: Updating Phase
1020 |
1021 | After Mounting the Component, Anytime, the state or props change the component will enter this phase.
1022 |
1023 |
1024 |
1025 |
1026 |
1027 |
1028 | #### :triangular_flag_on_post: Unmounting Phase
1029 |
1030 | This phase occurs when the component is about to be removed from the DOM and destroyed.
1031 |
1032 |
1033 |
1034 |
1035 |
1036 |
1037 | ### `constructor`
1038 | ##### Definition
1039 | ```javascript
1040 | constructor(props)
1041 | ```
1042 | `props` is the initial props that provided to the component
1043 |
1044 | ##### Calling Time
1045 | The constructor for a React component is called before it is mounted
1046 |
1047 | ##### Uses
1048 | 1. Initialize The Component State Object
1049 | 2. Bind The methods to the component
1050 |
1051 | ##### Notes
1052 | 1. If you didn’t use it , no need to implement it
1053 | 2. When implement it don’t forget to call `super(props)` before anything else.
1054 |
1055 |
1056 | ### `componentWillMount`
1057 | ##### Definition
1058 | ```javascript
1059 | componentWillMount()
1060 | ```
1061 | ##### Calling Time
1062 | invoked immediately before mounting occurs and before `render` method
1063 |
1064 | ##### Uses
1065 | 1. Update The Component State based on Props (Must use `setState` method)
1066 |
1067 | ##### Notes
1068 | 1. It runs one time through the Component Life Cycle
1069 |
1070 |
1071 | ### `render`
1072 | ##### Definition
1073 | ```javascript
1074 | render()
1075 | ```
1076 |
1077 | ##### Calling Time
1078 | Called After `componentWillMount` & `componentWillUpdate`
1079 |
1080 | ##### Uses
1081 | 1. Use States & Props to return a Single React Element represent the Component.
1082 | 2. We can return `null` or `false` to indicate that you don't want anything rendered
1083 |
1084 |
1085 | ##### Notes
1086 | 1. render method is required to be implemented.
1087 | 2. render method should be pure function.
1088 |
1089 |
1090 | ### `componentDidMount`
1091 | ##### Definition
1092 | ```javascript
1093 | componentDidMount()
1094 | ```
1095 |
1096 | ##### Calling Time
1097 | invoked immediately after a component is mounted
1098 |
1099 | ##### Uses
1100 | 1. Treat with DOM executed here
1101 | 2. Load data from remote server
1102 |
1103 | ##### Notes
1104 | 1. Run one time through the Component Life Cycle.
1105 | 2. If we use `setState` it will run render method another time
1106 |
1107 |
1108 | ### `componentWillReceiveProps`
1109 | ##### Definition
1110 | ```javascript
1111 | componentWillReceiveProps(nextProps)
1112 | ```
1113 | `nextProps` is the new provided props that still not attached to the component
1114 |
1115 | ##### Calling Time
1116 | invoked before a mounted component receives new `props`
1117 |
1118 | ##### Uses
1119 | 1. update the state in response to prop changes.
1120 |
1121 | ##### Notes
1122 | 1. Calling this method doesn’t mean the value of props has changed.
1123 | 2. Calling setState generally doesn't trigger this method.
1124 |
1125 |
1126 | ### `shouldComponentUpdate`
1127 | ##### Definition
1128 | ```javascript
1129 | shouldComponentUpdate(nextProps, nextState)
1130 | ```
1131 | `nextProps` is the new provided props that still not attached to the component
1132 | `nextState` is the updated state after using `setState` method on the previous hooks that still not attached to the component
1133 |
1134 | ##### Calling Time
1135 | invoked before rendering when new props or state are being received
1136 |
1137 | ##### Uses
1138 | 1. Allows your Component to exit the Updating Phase if there is no reason to apply a new `render`.
1139 |
1140 | ##### Notes
1141 | 1. When implement it don’t forget to return Boolean value.
1142 | 2. Returning `true` means that `render` method will be called.
1143 | 3. Returning `false` means that `render` method won’t be called.
1144 |
1145 |
1146 | ### `componentWillUpdate`
1147 | ##### Definition
1148 | ```javascript
1149 | componentWillUpdate(nextProps, nextState)
1150 | ```
1151 | `nextProps` is the new provided props that still not attached to the component
1152 | `nextState` is the updated state after using `setState` method on the previous hooks that still not attached to the component
1153 |
1154 | ##### Calling Time
1155 | invoked immediately before rendering when new props or state are being received
1156 |
1157 | ##### Uses
1158 | 1. perform preparation tasks before an update occurs
1159 |
1160 | ##### Notes
1161 | 1. you cannot call `setState` method here because it will make the component runs in recussive way and will raise maximumm stack exceed.
1162 |
1163 |
1164 | ### `componentDidUpdate`
1165 | ##### Definition
1166 | ```javascript
1167 | componentDidUpdate(prevProps, prevState)
1168 | ```
1169 | `prevProps` is the props that previously attached to the component but it is not now it's current props
1170 | `prevState` is the state that previously attached to the component but it is not now it's current state
1171 |
1172 | ##### Calling Time
1173 | is invoked immediately after updating occurs
1174 |
1175 | ##### Uses
1176 | 1. Treat with DOM executed here
1177 | 2. Load data from remote server
1178 |
1179 | ##### Notes
1180 | 1. You can control here if you want to get data from the remote server or not based on the changing of props
1181 |
1182 |
1183 | ### `componentWillUnmount`
1184 | ##### Definition
1185 | ```javascript
1186 | componentWillUnmount()
1187 | ```
1188 | ##### Calling Time
1189 | is invoked immediately before a component is unmounted and destroyed
1190 |
1191 | ##### Uses
1192 | 1. Perform any necessary cleanup (tear down) tasks in this method like removing timeouts or intervals that is used during component life cycle.
1193 |
1194 |
1195 |
1196 | ## Type checking with PropTypes
1197 |
1198 | We all know that JavaScript is Dynamic Data Typed Language so there is no restrictions on variables types. This feature gives us the felixibility in many cases but in other cases in order to improve your code quality and to ensure that everything works fine we need to check the types of variables. From this prespective, The Type checking concept appears in many ways:
1199 |
1200 | - [TypeScript](https://www.typescriptlang.org/)
1201 | We can find that there is a complete language to solve this issue and other issues
1202 |
1203 | - [Flow](https://flow.org/)
1204 | A static type checker tool called that can be integrated with many IDEs
1205 |
1206 | - [PropTypes](https://github.com/facebook/prop-types)
1207 | A npm package that was made espcially for React Components Props type checking.
1208 |
1209 | > So let's introduce `PropTypes` in the following points.
1210 |
1211 |
1212 |
1213 |
1214 |
1215 | ### Use PropTypes
1216 | First we must install the `prop-types` npm package using the following command:
1217 |
1218 | ```
1219 | cd your-project
1220 | npm install --save prop-types
1221 | ```
1222 |
1223 | > Here is an exmample of how to use PropTypes:
1224 |
1225 | ```jsx
1226 | // import PropTypes package
1227 | import PropTypes from 'prop-types';
1228 |
1229 | class User extends React.Component {
1230 | render() {
1231 | return (
1232 |
1233 |
{this.props.name}
1234 |
{this.props.age}
1235 |
);
1236 | }
1237 | }
1238 |
1239 | // Add your Props types in order to be checked during app running
1240 | User.propTypes = {
1241 | name: PropTypes.string,
1242 | age: PropTypes.number
1243 | }
1244 |
1245 | ```
1246 |
1247 | Let's take a quick tour on `prop-types`
1248 |
1249 | ### Basic Types
1250 | ```jsx
1251 |
1252 | import PropTypes from 'prop-types';
1253 |
1254 | class Student extends React.Component { /* ... */ }
1255 |
1256 | Student.propTypes = {
1257 | name: PropTypes.string, // Define prop name as String type
1258 | age: PropTypes.number, // Define prop name as Number
1259 | isEgyptian: PropTypes.bool, // Define prop name as Boolean
1260 | scores: PropTypes.array, // Define prop name as Array
1261 | schedule: PropTypes.object, // Define prop name as Object
1262 | study: PropTypes.func, // Define prop name as Function
1263 | };
1264 |
1265 | ```
1266 |
1267 | > Note: Use 'object' PropType is not recommended, Use [shape](#shape) propType instead.
1268 |
1269 | ### Enums
1270 |
1271 | PropTypes Enums can be:
1272 | - Prop value be one of list of specific values.
1273 | - Prop type be one of list of specific types.
1274 |
1275 | > Here is an example of how to do that:
1276 |
1277 | ```jsx
1278 | import PropTypes from 'prop-types';
1279 | class Student extends React.Component { ... }
1280 |
1281 | Student.propTypes = {
1282 | subject: PropTypes.oneOf([‘React’, ‘Angular’]), // subject value may be React or Angular only
1283 | id: PropTypes.oneOfType([ // id data type may be Number or String only
1284 | PropTypes.number,
1285 | PropTypes.string
1286 | ])
1287 | }
1288 | ```
1289 |
1290 | ### Collection of Specific Type
1291 | With PropTypes you can specify the data type of the composite typed props like `objects` or `arrays`.
1292 |
1293 | > For Example:
1294 |
1295 | ```jsx
1296 | import PropTypes from 'prop-types';
1297 | class Student extends React.Component { ... }
1298 | Student.propTypes = {
1299 | scores: PropTypes.arrayOf(PropTypes.number),
1300 | scoreObj: PropTypes.objectOf(PropTypes.array)
1301 | }
1302 | ```
1303 |
1304 | ### Shape
1305 | `shape` PropType is used to design your object `prop` structure. it's mostly used instead of `object` propType and also recommended to be used.
1306 |
1307 | > Here is an example:
1308 |
1309 | ```jsx
1310 |
1311 | import PropTypes from 'prop-types';
1312 | class Student extends React.Component { ... }
1313 | Student.propTypes = {
1314 | info: PropTypes.shape({
1315 | name: PropType.string.isRequired,
1316 | age: PropType.number,
1317 | courses: PropType.arrayOf(Proptype.string)
1318 | })
1319 | }
1320 | ```
1321 |
1322 | So `info` prop will be an object that have `name` string property and it is required, `age` number property and `courses` array property. So we define the object more accurately.
1323 |
1324 | ### instanceOf
1325 | We can check if the prop is instance of any prototype or custom object using `instanceOf` method.
1326 |
1327 | ```jsx
1328 | import PropTypes from 'prop-types';
1329 | class Student extends React.Component { ... }
1330 | Student.propTypes = {
1331 | schedule: PropTypes.instanceOf(Schedule) // Check if the value is instance of Schedule Object
1332 | }
1333 | ```
1334 |
1335 | > Note: You can use it instead of `object` propType and make custom models (objects) with a specific structure to check if the prop value is instance of it or not.
1336 |
1337 | ### isRequired
1338 | We can specify if the `prop` is required or optional.
1339 |
1340 | ```jsx
1341 | import PropTypes from 'prop-types';
1342 | class Student extends React.Component { ... }
1343 | Student.propTypes = {
1344 | name: PropTypes.string.isRequired, // will raise error if name is not provided
1345 | bio: PropTypes.string, // will check only if the bio value provided
1346 | }
1347 | ```
1348 |
1349 | > Note: Instead of make the `prop` required, you can assign to it a default value if it's not provided. See [defaultProps]('#defaultprops') section.
1350 |
1351 |
1352 |
1353 | ## Practice React
1354 | > Build [Guess it](https://github.com/AhmedMoawad/guess-it-game) Game
1355 |
1356 | Here we reach the point that you can apply what we have learn above to build real application and in order to do that I create an educational and simple game called [Guess it](https://github.com/AhmedMoawad/guess-it-game) to start building react apps. Fork it's repo and start playing with it.
1357 |
1358 |
1359 |
1360 |
1361 |
1362 |
1363 |
1364 | ## Final Words
1365 | I hope that this tutorial helps to understand React better and make you able now to develop a solid web application using React. We are still improve it and will not stop improving and updating it :smile:.
1366 |
1367 |
1368 |
1369 | ## To Be Added
1370 | - [x] Add Guess it Game.
1371 | - [ ] Add Tips and Tricks Part 2.
1372 |
1373 | ## Author
1374 |
1375 | #### [Ahmed Moawad](https://github.com/AhmedMoawad)
1376 |
1377 |
1378 |
1379 | ## Contribution
1380 |
1381 | This tutorial intents to simplify the work with React and makes you understand every single line you code. So if anyone see that we can improve it, make it more infortmative and clarified.
1382 |
1383 | You can make a pull request with the changes or raise an issue.
1384 |
1385 |
1386 |
1387 | ## Support Us
1388 | You can support us with any of these ways:
1389 | - Add your valuable contribution to the repo.
1390 | - Add your :star: Star if you finds it helpful.
1391 | - Share it on your community.
1392 |
--------------------------------------------------------------------------------