React Training
Day 1
Bartosz Szczeciński
GFT Poland
Do you know JS?
created by Brendan Eich of Netscape in only 10 days
JavaScript is the most popular implementation of ECMA Script
Other implementations include Action Script used in Flash
ES3 and ES5 are the current "standard" as they are supported by all major browsers
Inconsitency
different browsers implemented JS differently
some didn't implement things at all, implement them
differently than other browsers
developers had to do two or three time as much work
to support things like event listeners
First Frameworks
Prototype, Mootools, jQuery were some of the most popular frameworks that emerged in and after 2006 - most of them are still in use today
First Frameworks
they allowed for a unified access to DOM, events and other JS parts of JS - while still not compatible with each other they allowed for the same code to run on different browsers
// jQuery
$('div.foo').on('click', function() {
alert('Hello!');
});
// mootools
$$('div.foo').addEvent('click', function() {
alert('Hello!');
});
// prototype
$('div.foo').observe('click', function() {
alert('Hello!');
});
First "mature" frameworks
as more complex applications were starting to emerge in the browser ecosystem people wanted a tool to ease their work and make it more like writing normal apps
Backbone, Javascript MVC and Knockout JS were some of the first frameworks aimed for developing big apps
Complete package
based on ideas of the previous frameworks, Angular (sometimes called Angular JS, ng) was introduced as a "complete package" solution for developing interactive single-page applications.
With the expansion of mobile market, Angular was often implemented with Apache Cordova to provide a "native like" experience for the use and required only knowledge of HTML an JS with some of the API to access real hardware
Thinking outside of the browser
in 2009 an project was started as ServerJS that aimed to provide an environent to JS outside of the browser, it was later renamed CommonJS.
One of the features was introduction of modules, which in 2010 was implemented in the npm project. This allowed for the creation of specialized modules that could connect with each other to form bigger software.
Do one thing - do it right
Going with the idea of doing one thing and doing it right Facebook developed a library which helped them solve issues of updating multiple pieces of UI from a single data store - ReactJS in 2011
It wasn't untill 2013 that the project went Open Source
Hello, React!
React in itself doesn't offer many features - it focuses mostly on high-performance UI updates. The language was inspired by XHP - a PHP (Hack) extension that allowed usage of XML directly in PHP code of Facebook projects.
If a developer requires state management, integration with REST enpoints, form validations etc. he is required to either roll out his own or to integrate third party solutions.
Going further
React idea was later expanded to React Native which allows developers to write code similar to normal ReactJS which is subsequently compiled to either Android or iOS binaries and ran as a full-fledged apps, not as apps embeded within a browser window.
This allows developing faster, almost native level applications.
React native is not yet production ready - it has a small library of components and has many open issues.
State of JS - 2016 and beyond
rapid expansion to browsers and beyond
new features introduced in big bulks and small doses - ES6, ES Next
a new tool for every project, a new tool every month
bigger expectations, bigger apps, more security risks
State of JS - developers
constant changes in technology stack
"JS Fatigue"
breaking changes in app
NodeJS
Up until recently JavaScript was mostly seen as an browser-ran language. In the past years many projects aimed at providing an runtime environment that allowed to build backend and other applications in JS, of which Node.js is the most popular.
Node provides a tool which can either run .js files or provide and interactive REPL environment which allows the user to write code and see the results in the CLI window. By default node provides a package manager - npm.
NodeJS
Node is NOT a framework, although it's modular structure and the fact that parts of it are written in JS allow developers to use its components as parts of other frameworks.
Node is NOT an JS engine - by default it uses Google's V8
engine that is part of Chromium project but there are also forks using Chakra Core engine from Internet Explorer.
NodeJS - Compatibility
It's worth noting that even though Node ES6 compatibility is higher than that of Chrome, it's still not 100%
NPM
npm is both the name of the client and the repository containing various open source components and providing dependency resolving, updating and more.
The most important part of every npm project is the package.json file. You should always create a package.json file for your project. To do so simply call `npm init .` in the root directory.
You can also run `npm init . --yes` to create a file with all defaults set.
NPM - usage
# install all packages for current environment found in package.json,
# along with their dependencies
$ npm install
# install a package in its current version and
# save it as a dependency, dev dependency or install it globally
$ npm install package-name` (--save, --save-dev, --global)
# update all packages keeping the package versions compatible to those in package.json
$ npm update
# start the default script provided with the project
$ npm start
# start the default tests
$ npm test
# run an arbitrary script provided by the developer
$ npm run script-name
NPM - package.json
{
"name": "my_package",
"version": "1.0.0",
"dependencies": {
"my_dep": "^1.0.0"
},
"devDependencies" : {
"my_test_framework": "^3.1.0"
}
}
Every NodeJS project / npm package should contain an package.json file, consisting of at least its name and version.
Make sure to not create a project with an already taken name, or name of a package you will use (eg. "react") because it will enter a dependency loop.
NPM - symver
~version # "Approximately equivalent to version"
^version # "Compatible with version"
version # Must match version exactly
>version # Must be greater than version
>=version # etc
1.2.x # 1.2.0, 1.2.1, etc., but not 1.3.0
http://sometarballurl # URL of the .tgz file
* # any version
latest # Obtains latest release
Every package must have its version provided in symver compatible format. package.json can specify which version will your project use:
NPM - shrinkwrap
$ npm shrinkwrap
# package.json
{
"name": "A",
"version": "1.1.0",
"dependencies": {
"B": {
"version": "1.0.1",
"from": "B@^1.0.0",
"resolved": "https://registry.npmjs.org/B/-/B-1.0.1.tgz",
"dependencies": {
"C": {
"version": "1.0.1",
"from": "org/C#v1.0.1",
"resolved": "git://github.com/org/C.git#5c380ae319fc4efe9e7f2d9c78b0faa588fd99b4"
}
}
}
}
}
Some times we need to use a specific version of a package and even though we declare it so in the package.json, a dependency might update its package.json and get a new file.
To stop this we can use shrinkwrap:
JS of tomorrow - TODAY!
ES6 or ECMSScript 2015 is the most up-to-date standard implemented by JavaScript in the most popular browsers.
It introduces a lot of new and helpful concepts and if not required it is highly recommended to learn and use it in the upcoming projects.
Please note that some of the ES6 features might not be supported by various browsers - to get around that we will introduce the concept of transpiling later on.
Modules
# test.js
function test() {
// code
}
var PI = 3.14;
exports = {
test: test,
PI: PI
}
# test2.js
function test2() {
// code
}
modules.exports = test2;
# app.js
var myLib = require('./test.js');
myLib.test();
myLub.PI;
var otherLib = require('./test2.js');
otherLib();
# test.js
export var PI = 3.14;
function test() {
// code
}
export test;
export default test2() {
// code
}
# app.js
import test2 from "./test.js";
import { PI, test } from "./test.js";
import * as myLib from "./test.js";
test2();
console.log(PI);
myLib.test();
Scoping
var a;
a = 1;
let b = 2;
const c = 3;
const c = 4; // SyntaxError - can't redefine the const
console.log(a); // 1
(function() {
console.log(a); // 1
console.log(b); // 2;
})();
if(true) {
var d = 5;
let e = 6;
}
console.log(d); // 5;
console.log(e); // ReferenceError - e is not defined
Arrow functions
function Counter() {
this.value = 10;
setInterval(function count() {
this.value++;
console.log('Value is ' + this.value);
}, 1000);
}
var c = new Counter();
function Counter() {
this.value = 10;
setInterval(() => {
this.value++;
console.log('Value is ' + this.value);
}, 1000);
}
var c = new Counter();
Context matching, destructuring
function matchObject({x, y}) {
return x * y;
}
matchObject({x: 5, z: 8, y: 2}); // 10
function getMyObject() {
return {
x: 1,
y: 3,
z: 18
}
};
let { x, z, y } = getMyObject();
console.log(x, y, z); // 1, 3, 18
let [a, b, c = 5] = [1, 2];
console.log(b); // 2
console.log(c); // 5
Destructuring
Importing a module is NOT using the destructuring syntax!
Property value shorthand
let PI: 3.15;
function myMathEquation() {
// code
}
export {
PI: PI,
myMathEquation: myMathEquation
};
let PI: 3.15;
function myMathEquation() {
// code
}
export {
PI,
myMathEquation
};
Template literal
console.log("this is" +
"an example" +
"of multi-line string");
let a = 1;
console.log("values of a is " + a);
console.log(`this is also
an example of multi-line
string`);
let a = 2;
console.log(`a = ${a}`);
Tagged templates
function test(str) {
return str[0].toUpperCase();
}
let upperCase = test`this is an example string`;
console.log(upperCase); // THIS IS AN EXAMPLE STRING
function hasVariables(str, ...variables) {
console.log(str); // [ 'a = ', ', b = ', '' ]
console.log(variables); // [1, 2]
}
let a = 1, b = 2;
hasVariables`a = ${a}, b = ${b}`;
console.log("A panda looks something like this: 🐼");
Classes
class Person {
greet() {
return this.greetingForm + ", " + this.personName;
}
}
class PersonFromGermany extends Person {
constructor(name) {
super(); /* need to call super() if you are extending a class and overriding the constructor */
this.personName = name;
this.greetingForm = "Guten tag";
}
}
const me = new PersonFromGermany("Bartosz");
console.log(me.greet()); /* Guten tag, Bartosz */
class Test {
set a(value) { this._a = value; }
get a() { return this._a; }
}
const obj = new Test();
obj.a = 5;
console.log(obj.a);
Promises
new Promise(function( resolved, rejected ) {
// asynchronous logic
});
A promise can be in one of the 3 states:
pending: initial state, not fulfilled or rejected.
fulfilled: meaning that the operation completed successfully.
rejected: meaning that the operation failed.
The promise object has 2 public methods:
then(onResolve, onReject) - will be called when the promise is fulfilled, it can return another promise to chain them
catch(onReject) - it is an alias to then(null, onReject)
Promises
const p = new Promise(function(res, rej) {
setTimeout(res, 1000);
}).then(() => {
console.log("A second passed!"); /* will be called after 1 second */
});
new Promise(function(res, rej) {
setTimeout(rej, 1000);
}).then(() => {
console.log("A second passed, again!");
}).catch(() => {
console.log("It looks like the time stopped passing ...."); /* will be called after 1 second */
});
function second() {
return new Promise(function(res, rej) {
setTimeout(res, 1000);
});
};
second().then(() => {
console.log("A second passed ..."); /* called after 1 second */
return second();
}).then(() => {
console.log("And another one!"); /* called after 2 seconds */
return second();
}).then(second) /* called after 3 seconds - just return a new promise */
.then(() => console.log("Looks like we've skipped a second there ...")); /* called after 4 seconds */
High Order Functions
High order functions are functions that take functions as parameters and return new or changed functions.
function log(f) {
return function(arg) {
var val = f(arg);
console.log("Invoked with '" + arg + "' - got '" + val + "'");
return val;
}
}
function toUpper(string) {
return string.toUpperCase();
}
log(toUpper)("small case text"); /* Invoked with 'small case text' - got 'SMALL CASE TEXT' */
const loggedToUpper = log(toUpper); /* can now just do loggedToUpper("text"); */
Transpiling
Because there is no 100% support of ES6 in many of the browsers we need to use so called transpilers or source-to-source compilers which take source code written in one language and output the same application in another.
In our case we will be using babel to transpile ES6 to ES5.
We might also use solutions known as Polyfill to add functionality not supported in target browsers
(for example IE11 doesn't support Promises).
Transpiling
React Training 2016
By btmpl
React Training 2016
- 389