React.js
Dec 2017, ATD13, @vekzdran
A VERY SIMPLE 101 GUIDE
...that will persuade you(r dev team) to start using it!
👏👏🏻👏🏼👏🏽👏🏾👏🏿
PRESENTER
VEDRAN MANDIć
@vekzdran
.NET Devil
JS LOVER
@MOGYAPP
@FIVENYC
PRESENTATION Agenda
80%
-
how it looks
-
what it is? + philosophy
-
the data(flow)
-
the lifecycle
-
the virtual DOM
-
recap with pros/cons
20%
-
demo & questions
included
-
trolling, sarcasm and 😀
-
one intentional bug 🐛
React.js fact check:
- Developed by Facebook
- Maintained publicly on GitHub
- Used by Facebook, Instagram, AirBnB, Netflix...
- A declarative, efficient, and flexible JavaScript library for building user interfaces
- First release Mar 2013
- Current major version is 16, released on Sept 2017
- MIT licensed from 15.6 version
n <= 10000
IT MUST BE .JS MAGIC ...
var React = require("react");
var createReactClass = require("create-react-class");
var Link = require("react-router").Link;
var SearchBox = require("../components/SearchBox.js");
var Header = createReactClass({
render: function() {
return (
<div className="header">
<Link to="/">
<h1>Weather App</h1>
</Link>
<SearchBox className="searchBoxSmall" />
</div>
);
}
});
// CommonJS module approach
module.exports = Header;
... possibly even worse 🔮witchcraft ✨than Angular 2, 4 and 5
Well... IT's just javascript...
render: function() {
// the <div>
return React.createElement("div", {className: "header"},
[
// the <Link>
React.createElement(Link, {to: "/"},
// the <h1>
React.createElement("h1", null, "Weather App")),
// the <SearchBox>
React.createElement(SearchBox, {className: "searchBoxSmall"}, null)
]
);
}
... syntactic sugar known as JSX
... that transforms to JavaScript!
ECMASCRIPT 6
import React, { Component } from "React";
import { Link } from "react-router";
import SearchBox from "../components/SearchBox.js";
class Header extends Component {
render() {
return (
<div className="header">
<Link to="/">
<h1>Weather App</h1>
</Link>
<SearchBox className="searchBoxSmall" />
</div>
);
}
}
export default Header;
... basically the standard for writing (any JavaScript app) React apps
ES6 transpiles into ES5/4/3 standards with e.g. Babel Transpiler
A jsx TL;DR
"JSX is like a healthy vegetable 🥕 that tastes like decadent chocolate 🍰 cake. You feel guilty, but it’s good for you."
Eric Elliot
oh Modern JavaScript ...
... (╯°□°) ╯︵ ┻━┻
NodeJS, npm, yarn, Webpack,
rollup, Headless Chrome, LightHouse...
...HTML in .JS(X)?! 😨
return (
<BattleAlert gameId={this.props.gameId}>
<h1>Hello {username}, welcome to: {this.props.gameName}</h1>
<ConfirmBattle
isLoading={this.state.isLoading}
onInitiateBattle={this.handleInitiateBattle} />
</BattleAlert>
);
...AHH, A(nother) {TEMPLATING} ENGINE!
...TON OF STUFF* DECLARED and (data)bound IN 1 FILE!?
please again... W'at is this!? :)
SEPARATION OF CONCERnS?
DO YOU EVEN (a bit)?
¯\_(ツ)_/¯
yes, SEPARATION OF... concerns and
SELF CONTAINED COMPONENTS
...concerNs are INDEED separated
- It's "just" (a) JavaScript (view library by Facebook)
- It's the V in MVC, but no models & no controllers
- Components are the building blocks
- Plain JS + JSX syntax + Virtual DOM
SO WHAT IS REACT ... ?
... it's like Lego, but with components!
-
All it does is render and delegate events.
-
It knows the data it needs to render.
-
It knows when to render it (when the data changes).
-
It knows how to render it efficiently.
- E. Elliot
It's
Just
efficient
rendering ✏️
And WHY COMPONENTS ?
...because they are:
- isolated
- composable
- testable
- reusable
- maintainable
UI components example again
hmm... NO MODELS, BUT WHERE's DATA?
Traditional 2-way bindings, nope- Data flows in 1-way
- Parent sends to Child(ren)
- Props and State...
-bind="text: starDate"
Props PASSES DATA* down...
...to child components
import PrettyPrint from "./PrettyPrint";
var Writer = React.createReactClass({
render: function () {
return (
<PrettyPrint text="Foo... Bar!" id={this.props.id} />
);
}
});
this.props is immutable
*also means functions, i.e. events
var PrettyPrint = createReactClass({
render: function() {
return (
<p id={this.props.id} className="aPrettyParagraph">
{this.props.text}
</p>
);
}
});
#REMINDER #neverforget
...JSX is just a bunch of .js nested React.createElement() calls
STATE IS MUTABLE
USING STATE Is optional...
var PrintRandomNumber = createReactClass({
setRandomNumber: function() {
// changing state will fire render()
this.setState({ number: Math.random() });
}
render: function () {
return <PrettyPrint text="{this.state.number}" />;
}
});
// This a 'Stateless Functional Component'
// Pure functional transforms of input, with zero boilerplate.
var ICanOnlyRenderWithProps = function(props) {
return (
<p id={props.id} className="statlessPrettyParagraph">
{this.props.text}
</p>
);
};
mutating state will fire render() and all child render() methods
DID you notice the bug? 🐛
TAKE CARE HOW YOU PASS (which) value (TYPE) to props...
var PrintRandomNumber = createReactClass({
setRandomNumber: function() {
// changing state will fire render()
this.setState({ number: Math.random() });
}
render: function () {
return <PrettyPrint text="{this.state.number}" />;
}
});
ahm... also getInitialState() is missing :)
component life
MOUNT -> update -> UNMOUNT
Mounting (component mounts DOM):
Updating (state mutates or new props come):
Unmounting:
getDefaultProps() -> getInitialState() -> componentWillMount()
render() -> children component(s) lifecycle
componentDidMount()
componentWillReceiveProps() -> shouldComponentUpdate() - >componentWillUpdate()
render() -> children component(s) lifecycle
componentDidUpdate()
componentWillUnmount() -> children component(s) lifecycle
Instances destroyed for GC
COMPARED TO GOOD Ol' CONTROL life
MOUNT -> update -> UNMOUNT
Mounting:
Updating (on data change):
Unmounting:
getInitialState() -> onLoad
render() -> onRefreshUI + run nested control events
componentDidMount() -> onAfterUIRefreshedFirstTime
shouldComponentUpdate() - > onBeforeRefreshUI
render() -> onRefreshUI + run nested control events
componentDidUpdate() -> onAfterRefreshUI
componentWillUnmount() -> onUnload + run nested control events
virtual dom
to solve the problems of the original dom
- a HTML DOM abstraction
- light and deattached from browser specif.
-
does not deal with drawing stuff and UI
- React updates vDOM
- vDOM updates DOM only for diffs!
- efficient thanks to good diff algos
- a single top level event listener
Don't you know HTML dom is ALSO an abstraction ? 💥
It's so complex and cool - South Park s14e10
But what's the matter with THE normal dom?
- When it grows... 🔥 traversing it becomes very slow
- SPAs these days, a ton of divs...
- abusing $(".getMAGIC_STRINGNode")🔥 ...all the nodes
- a ton of event listeners, try finding & editing one, memory!?
- data-mySuperDataInDom* !? (admit you've done this 💩)
HTML DOm bad keypoints
- hard to manage
- inefficient
that React + vDOM solve
LEt's RECAP
PRO
CONTRA
- declarative (JSX)
- it is plain js
- no framework specific magic
- just the V of MVC
- Separation of C/SCC
- efficient vDOM
- functional style is a +
- easy to learn
-
React + Redux: < 42kB
-
server rendering
-
pluggable on any page
- will not play nice with other existing libs like DOM and $
- optimize rerendering
- store state management...
- a dev philosophical shift
- team knowledge dep.
- split front/back arch.
- server rendering -> SEO, general issue of PWA
- overkill /w state management
Apples VS Orangutans?
ReactDOM.render(<AtdDemo />, rootEl);
THX + Q&A
ATD13 - React Dead Simple 101 Guide
By Vedran Mandić
ATD13 - React Dead Simple 101 Guide
This is a short and fun presentation about React.js from Facebook that is used for building powerful web UIs.
- 1,214