-
Notifications
You must be signed in to change notification settings - Fork 4
React
To begin with, some ES6 syntax concepts should be explained.
Classes are a kind of data structure which allow for certain OOP principles. Their syntax looks something like:
class MyClass {
constructor() {
...
}
someFunction() {
...
}
}
The constructor
function is a special function that is only called when the class is constructed using the following syntax: new MyClass()
.
The function someFunction
is a member of the class, and all instances of MyClass
will have this function.
Classes can also extend other classes, using the following syntax:
class MyOtherClass extends MyClass {
constructor() {
super();
...
}
}
The super
function called in the constructor is a reference to the extended class' constructor function. It must be called from within the constructor, and can only be called from within the constructor.
Export statements are a syntax that allow modules to expose certain portions of their contents for the consumption from other modules. Export statements come in a few forms:
-
export var myVar = 4
- Expose a variable or constant namedmyVar
-
export function myFunction() {...
- Expose a function called myFunction -
export class MyClass {...
- Expose a class called MyClass -
export default <anything>
- Expose a variable, constant, function, class, or anything else as the default export of the module -- this is explained more in Import
Import statements are a syntax that allow the communication of various ES6 modules. Import statements come in a few forms:
-
import SomeDefault from './SomeModule'
- Import the default export from the module file "SomeModule.js" in the same directory as the importing module -
import { someVar, someFunction } from './SomeModule'
- Import variables, functions, or any other exported member of the module "SomeModule.js" -
import * as SomeModule from './SomeModule'
- Imports all values from "SomeModule.js". The values will appear as properties on theSomeModule
object with their property keys being the same as their exported name. The default export appears on this object asSomeModule.default
. -
import <any import statement> from 'some-module'
- Imports a module from the "node_modules" directory. Notice that thefrom
location is not a relative path -- this is what tells the transpiler that this is a "node_modules" dependency.
Lambdas are an alternate syntax for functions in ES6. They are also sometimes called "arrow functions". The syntax looks something like:
var myFunction = (someParam) => {
...
}
This is identical to:
function myFunction(someParam) {
...
}
Lambdas also have a syntax without curly braces, specifically:
var myFunction = (someParam) => someParam.toString();
Using this syntax, body of the lambda can only be a single expression, and the created function will return the value evaluated by the expression.
The biggest difference between functions and lambdas is that, in a function, the this
object ends up being the object on which it is a member, or if it is not a member on an object, then it ends up being the window
object.
By contrast, in a lambda function, the this
object is the same as the parent context. For instance:
class MyClass {
constructor() {
this.callCount = 0;
}
doStuff() {
const iterator1 = () => {
this.callCount += 1;
}
function iterator2() {
this.callCount += 1;
}
iterator1()
iterator2()
}
}
var myObject = new MyClass();
myObject.doStuff();
console.log(myObject.callCount);
In this instance, myObject.callCount
will only be 1. That is because, in iterator1
, this
is the same as myObject
. By contrast, in iterator2
, this
is the same as window
. Therefore, only the this.callCount += 1;
in iterator1
affects the value of myObject.callCount
.
JSX looks a lot like HTML or any other XML-like markup language. An example could be:
<div className='some-class' onClick={ (ev) => clickHandler(ev) }>
{ someVar }
</div>
In this example, we are creating a JavaScript object representation of a div
element. It will have the html class of some-class
, when clicked, will call the clickHandler
function, and the contents of the div will be the value of someVar
.
JSX is the core syntax of React. It is how react renders elements and data onto the DOM.
Components, which we will explore later, can be used like elements in this manner:
<MyComponent myProp='foo'>
</MyComponent>
In this example, we have a component called MyComponent
with an attribute on it called myProp
. The attribute myProp
will end up appearing on its props
object. For more on that, see Props.
Props are the list of attributes on a component rendered in JSX. This comes in the form of an object with properties. These properties have keys matching the names of the attributes declared on the component in JSX. For example:
<MyComponent myProp='foo'>
</MyComponent>
In this instance, MyComponent
will have props.myProp
with a value of 'foo'
.
Stateless components are simply functions that take in a props
object and spit out JSX. An example would look like:
import React from 'react';
export default function MyComponent(props) {
return (
<div>
Hello, { props.myProp }
</div>
);
}
Stateful components are an ES6 class that extend the Component
class of react. They have a few key differences from stateless components, namely:
- The constructor takes in the
props
object. Thesuper
function in the constructor must be called by passing the props into it, likesuper(props);
- Their
props
are a property on the object. It is referenced usingthis.props
. - They have
state
, which is a property on the object. It is referenced usingthis.state
. You cannot modify this object outside of the constructor. Instead it is modified usingsetState
. - Stateful components have a
setState
function. It is referenced usingthis.setState
. It takes an object, and modifies the properties onstate
that appear on the object passed in.
An example of a stateful component might look like:
import React, { Component } from 'react';
export default class MyComponent extends Component {
constructor(props) {
super(props);
this.state = {
name: props.myProp,
greeting: 'Hello'
};
}
changeName(newName) {
this.setState({ name: newName });
}
changeGreeting(newGreeting) {
this.setState({ greeting: newGreeting });
}
render() {
return (
<div>
<input value={ this.state.name } onChange={ (ev) => this.changeName(ev.target.value) } />
<input value={ this.state.greeting } onChange={ (ev) => this.changeGreeting(ev.target.value) } />
<div>
{ this.state.greeting }, { this.state.name }
</div>
</div>
);
}
}