Introduction to React

Modern JavaScript

Modern JavaScript

JavaScript is being developed actively and gets frequent additions. The by far most used standardization is ECMAScript. It gets new features regularely, so for example you'll come across ES6 (also called ECMAScript2015), which added new features like block-scoped variables and more. Many of the new features are documented below.

CRA with Babel and Webpack

When using create-react-app to start your React project, you shouldn't need to touch your Webpack and Babel configuration for you unless you want to integrate some third-party dependency.

Babel

Babel is a JS compiler, which allows you to compile next generation JS to JS that runs in all browsers; so basically it ensures that your web app runs on older browsers (Browser Compatibility).

Webpack

Webpack is a module bundler; among others things it can combine all your JS files into a single one and handle imports etc. It uses Babel to compile your JS and can also process other assets like CSS or images.

let/const

let and const were introduced in ECMAScript2015 (ES6) and are a new way to declare variables. You should avoid var whenever possible, since var declares global variables.

Variables declared with let are block-scoped and const variables are final, so their value can't be reassigned.

Don't confuse const with Object.freeze(). A const variable cannot be reassigned, but if it contains an object its values can still be changed:

const x = { a: 1 }
x.a = 2
console.log(x.a) // 2
const y = { a: 1 }
Object.freeze(y) // Object can't be mutated anymore
y.a = 2 // doesn't change object and doesn't throw an error
console.log(y.a) // 1

Template literals

Template literals/template strings are an easy way to concatinate text with variables.

The following are equivalent:

const x = 1
console.log("x is " + x + "!")
console.log(`x is ${x}!`)

As you can see, you simply have to use ` (backticks) and wrap variables (or expressions) within ${}.

Arrow functions

Arrow functions are a syntax to write in-line functions. The following are (in this example) the same:

function increment(number) {
return number + 1
}
// function can be assigned to variable
const increment = (number) => {
return number + 1
}
// when omitting the curly braces, the expression after the => will automatically be returned
// this only works when the => is followed by a single expression
const increment = (number) => number + 1
// you can omit the parantheses around the function parameters when it has only a single parameter
const increment = (number) => number + 1
console.log(increment(1)) // prints '2'

Normal functions and arrow functions aren't equivalent, though. Normal functions have their own this, arrow functions do not.

Consider the following example: TODO:

Handling Promises

Promises are a way to handle an asynchronous program flow.

For example, when making a HTTP request it will take some time till you receive a response. While waiting for that response, you don't want your program to block.

fetch("http://example.com/api")
.then((response) => console.log(response.json()))
.catch((error) => {
console.error("Error:", error)
})

The function passed to the then() method get executed as soon as the fetch() call receives it's answer - the promise gets resolved. When the promises gets rejected, the function passed to catch() will be executed.

async/await

To make working with promises more comfortable and avoid too many nested .then() calls, you can use async/await. You can await calls to asynchronous functions and block the current function till the promises which is being awaited is resolved.

You can only use await in an asynchronous function.

async function getData() {
try {
// await blocks till it receives the server's response
const response = await fetch("http://example.com/api")
return response
} catch (error) {
return error
}
}

Object assignment with same key/value names

When you want to assign a key a value in an object and the key is the same as the variable's name you would like to use as the value, it suffices to just write the key.

So the following are equivalent:

const myVariable = 1
let obj = { myVariable: myVariable }
// equivalent
obj = { myVariable } // same as { myVariable: myVariable }

Destructuring

The destructuring makes it possible to unpack values from arrays or objects into variables.

const array = [1, 2, 3]
const [a, b, c] = array // a = 1, b = 2, c = 3
const [first, ...rest] = array // first = 1, rest = [2, 3]
const object = { x: 1, y: 2, z: 3 }
// Variables must have the same name as the object's key
const { x, y, z } = object // x = 1, y = 2, z = 3
// If you want to use different variable names than the object's keys,
// you can do that the following way:
const { x: i, y: j, z: k } = object // i = 1, j = 2, z = 3
let { x: myX, ...rest } = object // myX = 1, rest = { y: 2, z: 3}

import/export (ES modules)

When working with node you might also come across require() and exports; that means you're working with commonjs modules. This section, however, describes ES6 modules, which differ in syntax.

Export and import default

Every file can have a maximum of one default export:

config.js
const font = "#51D415"
export default primary

Importing the default export looks like the following:

main.js
// Default export will be imported with the name "myFont"
// You can import it with any name you want
import myFont from "./config.js"

Named exports

config.js
const colors = {
primary: "#ff0000",
secondary: "#ffff00",
background: "#ffffff",
}
const fontSizes = {
heading: "36px",
text: "12px",
}
export { colors, fontSizes }
// you can also export it under an alias:
// export { colors as myAlias }
main.js
// here, the name matters
import { colors, fontSizes } from "./config.js"
// Or import it with a different name:
// import { colors as themeColors} from './config.js'

Modern JS Example

// port has default value of 80
const get = async ({ host, port = 80, route, params }) => {
let paramsString = ""
for (key in params) {
paramsString += `?${key}=${params[key]}`
}
return await fetch(`https://${host}:${port}/${route}${paramsString}`)
}
const options = {
host: "example.com",
port: 8080,
route: "api",
params: { search: "apple" },
}
get(options)
.then((response) => console.log(response))
.catch((error) => console.log(error))
Edit this page on GitHub