React.js
Mar 2018, DEVUGZG, @vekzdran
A VERY SIMPLE 101 GUIDE
...that will persuade you(r dev team) to start using it!
PRESENTER
VEDRAN MANDIć
@vekzdran
MCT
MCSD: Web Apps
.NET Dev(il)
JS LOVER
@FIVENYC
PRESENTATION Agenda
>98%
-
how it looks
-
what it is? + philosophy
-
the data(flow)
-
the lifecycle
-
the virtual DOM
-
recap with pros/cons
???%
-
demo & questions
included
-
jokes, sarcasm and 😀
-
one intentional bug 🐛
React.js fact check:
- browser UI front-end lib developed by Facebook
- Maintained publicly on GitHub
- Used by Facebook, Instagram, AirBnB, Netflix...
- A declarative, efficient, and flexible JS library for building browser UIs
- First release Mar 2013
- Current latest version is 16.2, released on Nov 2017
- MIT licensed from 15.6 version
n <= 10000
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> recursively calls React.createElement in itself
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, Babel transpiler, TypeScript, Webpack, rollup, Headless Chrome, LightHouse...
Chrome updates every 3 minutes... why is Addy Osmani doing this?
...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 component 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 transformation 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 OF 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 + nested control events
- componentDidUpdate() -> onAfterRefreshUI
- componentWillUnmount() -> onUnload + 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
REGULAR dom anybody?
SRC: https://www.huffingtonpost.com/2014/04/04/american-forests-big-tree_n_5094798.html?slideshow=true#gallery/314956/26
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) + plain ES6+
- 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
-
TypeScript/Flow
-
pluggable on any page
-
E2E test frameworks
- will not play nice with other existing libs like DOM and $ (but portals!)
- optimize rerendering
- store state management...
- a dev philosophical shift
- team knowledge dep.
- split front/back arch.
- server rendering -> SEO, general issue of PWA
Apples VS Orangutans?
⚛ Where 👓should I START LEARNING? 📚
ReactDOM.render(<DevUgZgDemo />, rootEl);
THX + Q&A
React.js - A friendly 101 intro
By Vedran Mandić
React.js - A friendly 101 intro
This is a short and fun presentation about React.js from Facebook that is used for building powerful web UIs.
- 1,239