SlideShare une entreprise Scribd logo
1  sur  134
Télécharger pour lire hors ligne
Basic ReactJS
for Programmers
by Dr. David Rodenas
Origin
@drpicox
FB about MVC
3
https://youtu.be/nYkdrAPrdcw?t=10m20s
2014
@drpicox
FB about MVC
4
“MVC works pretty well
for small applications…
but it doesn’t make room
for new features.”
“Flux is a single direction data flow,
that avoids all the arrows
going on all directions
what makes really
hard to understand the system.”
@drpicox
FB about MVC
5
“Let’s see a real good example: FB chat”
“How we get to the point, so we were annoying our
users so much the just they wanted us to fix chat?”
“The problems here were:
• The code has no structure
• It was very imperative, that makes it fragile
• It loose a lot of the original intend behind it, its hard to tell what it tries [to do]
• Add more features only gets this code larger
• We had our most annoying chat bug happen over and over
• We were always fixing some pretty good edge case, the whole system was fragile
• …
• This code becomes more fragile with the time.
• No member of the team wanted to touch it, they wanted to jump to any other bug.”
@drpicox
FB about MVC
6
flux
@drpicox
FB about Rendering
7
“Imperative Rendering”
“If renders all each time
the screen flickers”
“We wanted always render all, no matter what”
“Here is where React comes in.”
ReactJS
@drpicox
Prerequisite
Make an account in codepen.io
@drpicox
Prerequisite
Install React Developer Tools
Basics
@drpicox
Hello World
<!-- hello-world.html -->
<div id="root"></div>
// hello-world.js
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('root')
);
12
https://facebook.github.io/react/docs/hello-world.html
@drpicox
Hello World
// This is translated by Babel to...
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('root')
);
// ...to this
ReactDOM.render(React.createElement(
'h1',
null,
'Hello, world!'
), document.getElementById('root'));
13
https://babeljs.io/repl
@drpicox
Do not fear change
• ReactJS only updates what changes
• Although everything is regenerated every time
• Open countdown example at codepen with chrome

http://codepen.io/drpicox/pen/yMKWGN
• Change View > Debug Mode (only works if registered)
• Inspect page
• You can see that only the span is updated

(although this crude code changes everything)
14
JSX
https://facebook.github.io/react/docs/introducing-jsx.html
@drpicox
JSX
// Just sugar syntax
const element = <h1>Hello, world!</h1>;
// It is just one object
const element = React.createElement(
"h1",
null,
"Hello, world!"
);
// one object that you can manipulate as object
16
@drpicox
JSX
// May I?
console.log(<h1>Hello!</h1>);
console.log(<h1>Hello!</h1>.toString());
console.log([<h1>Hello!</h1>]);
console.log({hello: <h1>Hello!</h1>});
console.log((() => <h1>Hello!</h1>)());
const salute = (what) => <h1>{what}!</h1>;
console.log(salute('Hello'));
17
@drpicox
JSX
// Have multiple elements (but one wrapper)
const element = <h1><span>Hello</span>, world!</h1>;
// Generates
const element = React.createElement(
"h1",
null,
React.createElement(
"span",
null,
"Hello"
),
", world!"
);
18
@drpicox
JSX
// It can be multiline (be careful using return)
const element =
<h1>
Hello, world!
</h1>;
19
@drpicox
JSX
// It can be multiline (better)
const element = <h1>
Hello, world!
</h1>;
20
@drpicox
JSX
// It can be multiline (recommended)
const element = (
<h1>
Hello, world!
</h1>
);
21
@drpicox
JSX
// Interpolate any JS expression
const user = {name:'bob', lastName:'hoskings'};
const element = (
<h1>
Hello, {user.name + ' ' + user.lastName}!
</h1>
);
// any expression, including JSX
const element = <h1>Hello, {<span>world</span>}!
22
@drpicox
JSX
// Add attributes (alias props)
const element = <div tabIndex="0">...</div>;
// Computed attributes
const element = <img src={user.imageUrl} />;
// class is className
const element = <div className="body">...</div>;
23
@drpicox
JSX - Cross-site-scripting
// It is just a string
const title = response.veryMaliciousInput;
// This is save
const element = <h1>{title}</h1>;
24
@drpicox
JSX
// Is XML-like
const element = (
<div>
Hello <br/> World
</div>
);
// Elements must be terminated
const element = (
<div>
Hello <br> World
</div>
);
25
Rendering Elements
https://facebook.github.io/react/docs/rendering-elements.html
@drpicox
Rendering Elements
// JSX elements are just memory objects
const element = <h1>Hello, world</h1>;
27
@drpicox
Rendering Elements
// Given an html DOM element
<div id="root"></div>
// they can be rendered inside DOM
const domElement = document.getElementById('root');
const reactElement = <h1>Hello, world</h1>;
ReactDOM.render(
reactElement,
/* into */ domElement
);
28
@drpicox
Rendering Elements
// As many times as you want
// react only updates changes
const domElement = document.getElementById('root');
let n = 0;
setInterval(() => {
ReactDOM.render(<h1>{n += 1}</h1>, domElement);
}, 1000);
29
Components and Props
https://facebook.github.io/react/docs/components-and-props.html
@drpicox
Component definition
// Functional component
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
// Class component
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
31
@drpicox
Render a Component
const element = <Welcome name="Dave" />;
32
@drpicox
Composing Components
function App() {
return (
<div>
<Welcome name="Alice" />
<Welcome name="Bob" />
<Welcome name="Dave" />
</div>
);
}
33
@drpicox
Refactoring Components
function Component(props) {
return (
<div className="Comment">
<div className="UserInfo">
<img className="Avatar"
src={props.author.avatarUrl}
alt={props.author.name}
/>
<div className="UserInfo-name">
{props.author.name}
</div>
</div>
<div className="Comment-text">
{props.text}
</div>
<div className="Comment-date">
{formatDate(props.date)}
</div>
</div>
);
}
34
@drpicox
Refactoring Components
function Avatar(props) {
return (
<img className="Avatar"
src={props.user.avatarUrl}
alt={props.user.name}
/>
);
}
35
<img className="Avatar"
src={props.author.avatarUrl}
alt={props.author.name}
/>
@drpicox
Refactoring Components
function Component(props) {
return (
<div className="Comment">
<div className="UserInfo">
<Avatar user={props.author} />
<div className="UserInfo-name">
{props.author.name}
</div>
</div>
<div className="Comment-text">
{props.text}
</div>
<div className="Comment-date">
{formatDate(props.date)}
</div>
</div>
);
}
36
@drpicox
Refactoring Components
function Component(props) {
return (
<div className="Comment">
<div className="UserInfo">
<Avatar user={props.author} />
<div className="UserInfo-name">
{props.author.name}
</div>
</div>
<div className="Comment-text">
{props.text}
</div>
<div className="Comment-date">
{formatDate(props.date)}
</div>
</div>
);
}
37
@drpicox
Refactoring Components
function UserInfo(props) {
return (
<div className="UserInfo">
<Avatar user={props.user} />
<div className="UserInfo-name">
{props.user.name}
</div>
</div>
);
}
38
@drpicox
Refactoring Components
function Component(props) {
return (
<div className="Comment">
<UserInfo user={props.author} />
<div className="Comment-text">
{props.text}
</div>
<div className="Comment-date">
{formatDate(props.date)}
</div>
</div>
);
}
39
@drpicox
Props are Read-Only
// Render must be read-only
function MissbehavingComponent(props) {
return <h1>{props.n += 1}</h1>;
}
40
State and Lifecycle
https://facebook.github.io/react/docs/state-and-lifecycle.html
@drpicox
Function to Class Component
function Clock(props) {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {props.time}.</h2>
</div>
);
}
42
@drpicox
Function to Class Component
class Clock extends React.Component {
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.props.time}.</h2>
</div>
);
}
}
43
@drpicox
Function to Class Component
class Clock extends React.Component {
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.props.time}.</h2>
</div>
);
}
}
44
@drpicox
Setup State
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {time: Date.now()};
}
render() { ... }
}
45
@drpicox
Setup State
class Clock extends React.Component {
constructor(props) { ... }
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.time}.</h2>
</div>
);
}
}
46
@drpicox
Lifecycle Methods
class Clock extends React.Component {
constructor(props) { ... }
componentDidMount() { /* TODO */ }
componentWillUnmount() { /* TODO */ }
render() { ... }
}
47
@drpicox
Lifecycle Methods
class Clock extends React.Component {
constructor(props) { ... }
componentDidMount() {
this.timerId = setInterval(
() => this.setState({time: Date.now()}),
1000
);
}
componentWillUnmount() { /* TODO */ }
render() { ... }
}
48
@drpicox
Lifecycle Methods
class Clock extends React.Component {
constructor(props) { ... }
componentDidMount() { ... }
componentWillUnmount() {
clearInterval(this.timerId);
}
render() { ... }
}
49
@drpicox
setState Asynchronous
// Wrong!
setState({counter: this.state.counter + 1});
// Correct
setState((prevState, props) => ({
counter: prevState.counter + 1
});
50
@drpicox
States are Merged
constructor() {
this.state = {posts: [], users: []};
}
componentDidMount() {
getPosts((posts) => this.setState({posts}));
getUsers((users) => this.setState({users}));
}
51
@drpicox
State Isolated
function App() {
return (
<div>
<Clock />
<Clock />
<Clock />
</div>
);
}
52
Handling Events
@drpicox
onEvent={fn}
function ButtonLogHello() {
function handleClick() {
console.log('The button is clicked');
}
return (
<button onClick={handleClick}>
click me
</button>
);
}
54
@drpicox
onEvent={fn}
// It received the event as parameter
function ALogHello() {
function handleClick(ev) {
ev.preventDefault();
console.log('The link is clicked');
}
return (
<a href="#" onClick={handleClick}>
click me
</a>
);
}
55
@drpicox
onEvent={fn}
// It can inline functions (are expressions)
function DivLogHello() {
return (
<button onClick={() => console.log('oh')}>
click me
</button>
);
}
56
@drpicox
Toggle Example
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true};
// This binding is necessary by `this`
this.handleClick = this.handleClick.bind(this);
}
handleClick() { ... }
...
57
https://facebook.github.io/react/docs/handling-events.html
@drpicox
Toggle Example
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true};
}
handleClick = () => { ... }
...
58
https://facebook.github.io/react/docs/handling-events.html
Conditional Rendering
https://facebook.github.io/react/docs/conditional-rendering.html
@drpicox
Conditional Rendering
function UserGreeting(props) {
return <h1>Welcome back!</h1>;
}
function GuestGreeting(props) {
return <h1>Please sign up.</h1>;
}
60
@drpicox
By return
function Greeting(props) {
const isLoggedIn = props.isLoggedIn;
if (isLoggedIn) {
return <UserGreeting />;
}
return <GuestGreeting />;
}
ReactDOM.render(
// Try changing to isLoggedIn={true}:
<Greeting isLoggedIn={false} />,
document.getElementById('root')
);
61
@drpicox
By variable
render() {
const isLoggedIn = this.state.isLoggedIn;
let button = null;
if (isLoggedIn) {
button = <LogoutButton onClick={this.handleLogoutClick} />;
} else {
button = <LoginButton onClick={this.handleLoginClick} />;
}
return (
<div>
<Greeting isLoggedIn={isLoggedIn} />
{button}
</div>
);
}
62
@drpicox
By && expression
function Mailbox(props) {
const unreadMessages = props.unreadMessages;
return (
<div>
<h1>Hello!</h1>
{unreadMessages.length > 0 &&
<h2>
You have {unreadMessages.length} unread messages.
</h2>
}
</div>
);
}
63
@drpicox
By ?: expression
render() {
const isLoggedIn = this.state.isLoggedIn;
return (
<div>
{isLoggedIn ? (
<LogoutButton onClick={this.handleLogoutClick} />
) : (
<LoginButton onClick={this.handleLoginClick} />
)}
</div>
);
}
64
@drpicox
Prevent Render
function WarningBanner(props) {
if (!props.warn) {
return null;
}
return (
<div className="warning">
Warning!
</div>
);
}
65
Lists and Keys
@drpicox
Remember...
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map((n) => n * 2);
console.log(doubled);
// [2, 4, 6, 8, 10]
67
@drpicox
Render Multiple
// Render a reactElements array
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
<li>{number}</li>
);
ReactDOM.render(
<ul>{listItems}</ul>,
document.getElementById('root')
);
68
@drpicox
Render Multiple
// Refactor into component
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
<li>{number}</li>
);
return (
<ul>{listItems}</ul>
);
}
const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
<NumberList numbers={numbers} />,
document.getElementById('root')
);
69
@drpicox
Key
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
<li key={number.toString()}>
{number}
</li>
);
return (
<ul>{listItems}</ul>
);
}
70
@drpicox
Key - index
const todoItems = todos.map((todo, index) =>
// Only do this if items have no stable IDs
<li key={index}>
{todo.text}
</li>
);
71
@drpicox
Key - Refactor Component
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
<li key={number.toString()}>
{number}
</li>
);
return (
<ul>{listItems}</ul>
);
}
72
@drpicox
Key - Refactor Component
function ListItem(props) {
return (
// Wrong! should not be here
<li key="props.number.toString()">
{props.number}
</li>
);
}
73
@drpicox
Key - Refactor Component
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
// Correct: key must remain with map
<ListItem key={number.toString()}
number={number} />
{number}
);
return (
<ul>{listItems}</ul>
);
}
74
@drpicox
Key - Uniqueness
// Cannot repeat keys in the same list, but...
function DoubleList(props) {
return (
<div>
<NumberList numbers={props.numbers} />
<NumberList numbers={props.numbers} />
<NumberList numbers={props.numbers} />
</div>
);
}
75
@drpicox
.map inside JSX
function NumberList(props) {
const numbers = props.numbers;
return (
<ul>
{numbers.map((number) =>
<ListItem key={number.toString()}
value={number} />
)}
</ul>
);
}
76
Forms
@drpicox
Controlled Components
class NameForm extends React.Component {
constructor() { ... }
handleChange = (event) => {
this.setState({value: event.target.value});
}
handleSubmit = (event) => { ... }
render() {
return (
<form onSubmit={this.handleSubmit}>
<input type="text"
value={this.state.value}
onChange={this.handleChange} />
</form>
);
}
}
78
@drpicox
Controlled Components
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
}
handleChange = (event) => { ... }
handleSubmit = (event) => { ... }
render() { ... }
}
79
@drpicox
Controlled Components
class NameForm extends React.Component {
constructor() { ... }
handleChange = (event) => {
this.setState({
value: event.target.value.toLowerCase()
});
}
handleSubmit = (event) => { ... }
render() { ... }
}
80
@drpicox
Textarea
<textarea
value={this.state.value}
onChange={this.handleChange}
/>
81
@drpicox
Select
<select
value={this.state.value}
onChange={this.handleChange}>
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
82
@drpicox
Multiple Inputs
<input
name="isGoing" type="checkbox"
checked={this.state.isGoing}
onChange={this.handleInputChange} />
<input
name="numberOfGuests" type="number"
value={this.state.numberOfGuests}
onChange={this.handleInputChange} />
83
@drpicox
Multiple Inputs
handleInputChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ?
target.checked : target.value;
const name = target.name;
this.setState({
[name]: value
});
}
84
Synchronized States
https://facebook.github.io/react/docs/lifting-state-up.html
@drpicox
Synchronizing - Consumer
// We want an <input> to generate new values for
function BoilingVerdict(props) {
if (props.celsius >= 100) {
return <p>The water would boil.</p>;
}
return <p>The water would not boil.</p>;
}
86
@drpicox
Synchronizing - Coordinator
class Calculator extends React.Component {
constructor(props) { ... }
handleChange = (e) =>
this.setState({temperature: e.target.value});
render() {
const temperature = this.state.temperature;
return (
<fieldset>
<legend>Enter temperature in Celsius:</legend>
<input value={temperature}
onChange={this.handleChange} />
<BoilingVerdict
celsius={parseFloat(temperature)} />
</fieldset>
);
}
}
87
@drpicox
Synchronizing - Producer
class Calculator extends React.Component {
constructor(props) { ... }
handleChange = (e) =>
this.setState({temperature: e.target.value});
render() {
const temperature = this.state.temperature;
return (
<fieldset>
<legend>Enter temperature in Celsius:</legend>
<input value={temperature}
onChange={this.handleChange} />
<BoilingVerdict
celsius={parseFloat(temperature)} />
</fieldset>
);
}
}
88
@drpicox
Synchronizing - Producer
class TemperatureInput extends React.Component {
constructor(props) { ... }
handleChange = (e) =>
this.setState({temperature: e.target.value});
render() {
const temperature = this.state.temperature;
const scaleName = scaleNames[this.props.scale];
return (
<fieldset>
<legend>Enter temperature in {scaleName}:</legend>
<input value={temperature}
onChange={this.handleChange} />
</fieldset>
);
}
}
89
@drpicox
Synchronizing - Producer
class Calculator extends React.Component {
constructor(props) { ... }
handleChange = (e) =>
this.setState({temperature: ...?});
render() {
const temperature = this.state.temperature;
return (
<div>
<TemperatureInput scale="c" ...? ...? />
<TemperatureInput scale="f" ...? ...? />
<BoilingVerdict
celsius={parseFloat(temperature)} />
</div>
);
}
}
90
@drpicox
Synchronizing - Producer
class TemperatureInput extends React.Component {
constructor(props) { ... }
handleChange = (e) =>
this.props.onTemperatureChange(e.target.value);
render() {
const temperature = this.props.temperature;
const scaleName = scaleNames[this.props.scale];
return (
<fieldset>
<legend>Enter temperature in {scaleName}:</legend>
<input value={temperature}
onChange={this.handleChange} />
</fieldset>
);
}
}
91
@drpicox
Synchronizing - Coordinator
class Calculator extends React.Component {
constructor(props) { ... }
handleChange = (e) =>
this.setState({temperature: ...?});
render() {
const temperature = this.state.temperature;
return (
<div>
<TemperatureInput scale="c" ...? ...? />
<TemperatureInput scale="f" ...? ...? />
<BoilingVerdict
celsius={parseFloat(temperature)} />
</div>
);
}
}
92
@drpicox
Coordinator - Inputs
class Calculator extends React.Component {
...
render() {
const scale = this.state.scale;
const temperature = this.state.temperature;
const celsius = convertIf(scale === 'f', temperature, toCelsius);
const fahrenheit = convertIf(scale === 'c', temperature, toFahrenheit);
return (
<div>
<TemperatureInput scale="c" temperature={celsius} ...? />
<TemperatureInput scale="f" temperature={fahrenheit} ...? />
<BoilingVerdict
celsius={parseFloat(celsius)} />
</div>
);
}
}
93
@drpicox
Coordinator Outputs
class Calculator extends React.Component {
...
handleCelsiusChange = (temperature) =>
this.setState({scale: 'c', temperature});
handleFahrenheitChange = (temperature) =>
this.setState({scale: 'f', temperature});
render() {
const scale = this.state.scale;
const temperature = this.state.temperature;
const celsius = convertIf(scale === 'f', temperature, toCelsius);
...
<TemperatureInput scale="c" temperature={celsius}
onTemperatureChange={this.handleCelsiusChange} />
<TemperatureInput scale="f" temperature={fahrenheit}
onTemperatureChange={this.handleFahrenheitChange} />
...
}
}
94
@drpicox
Coordinator Outputs
function convertIf(test, temperature, convert) {
if (test) {
return tryConvert(temperature, convert);
}
return temperature;
}
95
@drpicox
Exercise
96
https://codepen.io/drpicox/pen/ryrypJ
Exercise React Temperature
Component Composition
https://facebook.github.io/react/docs/composition-vs-
inheritance.html
@drpicox
Java 1.0
98
http://web.mit.edu/java_v1.0.2/www/apibook/javag2.htm
An application should override the action method (II-§1.10.1) of the button
or of one of its containing windows in order to cause some action to occur.
Button
+ action(...)
MyButton
+ action(...)
@drpicox
Java 1.1
99
In 1.1,we aimed at solving some major AWT (Abstract Window Toolkit)
deficiencies,with a strong focus on quality and performance.The AWT
enhancements include [...],a delegation-based event model,[...].
Button
+ actionActionListener(...)
https://www.cs.princeton.edu/courses/archive/fall97/cs461/
jdkdocs/guide/awt/index.html
<i> ActionListener
+ actionPerformed(...) = 0
MyActionListener
+ actionPerformed(...)
*
@drpicox
Java 1.2
100
When an Action object is added to such a container,the container: Creates a component that
is appropriate for that container (a toolbar creates a button component,for example),Gets
the appropriate property(s) from the Action object to customize the component (for example,
the icon image and flyover text)....
<i> Action
+ actionPerformed(...) = 0
+ isEnabled(): bool
+ setEnabled(b)
+ getValue(key): Object
+ putValue(key, value)
+ addPropertyChangeListener(...)
+ removePropertyChangeListener(...)
http://www.kbs.twi.tudelft.nl/Documentation/Programming/Java/
jdk1.2/api/javax/swing/Action.html
@drpicox
Children Composition
101
Card
Contents
@drpicox
Children Composition
<card>
<h1>Welcome</h1>
<p>
Find here a complete list
of all the things that you
love.
</p>
</card>
102
@drpicox
Children Composition
function Card(props) {
return (
<div className="card">
{props.children}
</div>
);
}
103
@drpicox
Many Children Composition
104
SplitPane
Left Right
@drpicox
Many Children Composition
<div class="SplitPane">
<div class="SplitPane-left">
<Contacts />
</div>
<div class="SplitPane-left">
<Chat />
</div>
</div>
105
@drpicox
Many Children Composition
function SplitPane(props) {
return (
<div className="SplitPane">
<div className="SplitPane-left">
{props.left}
</div>
<div className="SplitPane-right">
{props.right}
</div>
</div>
);
}
106
@drpicox
Many Children Composition
function App() {
return (
<SplitPane
left={ <Contacts /> }
right={ <Chat /> }
/>
);
}
107
@drpicox
Specialization
function Dialog(props) {
return (
<FancyBorder color="blue">
<h1 className="Dialog-title">
{props.title}
</h1>
<p className="Dialog-message">
{props.message}
</p>
</FancyBorder>
);
}
108
@drpicox
Specialization
function WelcomeDialog(props) {
return (
<Dialog
title="Welcome"
message="Thanks for visiting!" />
);
}
109
High Order Components (I)
https://facebook.github.io/react/docs/higher-order-
components.html
@drpicox
Like high order functions
const safeConvert = (convert) => {
return (temperature) => {
const input = parseFloat(temperature);
if (Number.isNaN(input)) {
return '';
}
const output = convert(input);
const rounded = Math.round(output * 100) / 100;
return rounded.toString();
}
}
111
@drpicox
Like high order functions
const safeConvert = (convert) => {
return (temperature) => {
...
}
}
const safeKelvinToCelsius =
safeConvert(kelvinToCelsius);
const celsius = safeKelvinToCelsius(kelvin);
112
@drpicox
Specific Component
class TemperatureInputCelsius extends React.Component {
handleChange = (e) => this.props.onTemperatureChange(
safeCelsiusToKelvin(e.target.value);
);
render() {
const temperature = this.props.temperature;
const celsius = safeKelvinToCelsius(temperature);
return (
<fieldset>
<legend>Enter temperature in Celsius:</legend>
<input value={temperature}
onChange={this.handleChange} />
</fieldset>
);
}
} 113
@drpicox
Specific Component
class TemperatureInputFahrenheit extends React.Component {
handleChange = (e) => this.props.onTemperatureChange(
safeFahrenheitToKelvin(e.target.value);
);
render() {
const temperature = this.props.temperature;
const celsius = safeKelvinToFahrenheit(temperature);
return (
<fieldset>
<legend>Enter temperature in Fahrenheit:</legend>
<input value={temperature}
onChange={this.handleChange} />
</fieldset>
);
}
} 114
@drpicox
Generic Component
class TemperatureInput? extends React.Component {
handleChange = (e) => this.props.onTemperatureChange(
toKelvin(e.target.value);
);
render() {
const temperature = this.props.temperature;
const local = toLocal(temperature);
return (
<fieldset>
<legend>Enter temperature in {scaleName}:</legend>
<input value={local}
onChange={this.handleChange} />
</fieldset>
);
}
} 115
@drpicox
Generic Component
function makeTemperatureInput(toKelvin, toLocal, scaleName) {
return class extends React.Component {
handleChange = (e) => this.props.onTemperatureChange(
toKelvin(e.target.value);
);
render() {
const temperature = this.props.temperature;
const local = toLocal(temperature);
return (
<fieldset>
<legend>Enter temperature in {scaleName}:</legend>
<input value={local}
onChange={this.handleChange} />
</fieldset>
);
}
}
}
116
@drpicox
Using Generic Component
const TemperatureInputCelsius = makeTemperatureInput(
safeCelsiusToKelvin,
safeKelvinToCelsius,
'Celsius'
);
const TemperatureInputFahrenheit = makeTemperatureInput(
safeFahrenheitToKelvin,
safeKelvinToFahrenheit,
'Fahrenheit'
);
const TemperatureInputKelvin = makeTemperatureInput(
identity,
identity,
'Kelvin'
); 117
@drpicox
Using Generic Component
const TemperatureInputCelsius = makeTemperatureInput(
safeConvert(celsiusToKelvin),
safeConvert(kelvinToCelsius),
'Celsius'
);
const TemperatureInputFahrenheit = makeTemperatureInput(
safeConvert(fahrenheitToKelvin),
safeConvert(kelvinToFahrenheit),
'Fahrenheit'
);
const TemperatureInputKelvin = makeTemperatureInput(
(x) => x,
(x) => x,
'Kelvin'
); 118
@drpicox
High Order Component
class Thermostat extends React.Component {
constructor(props) { ... }
handleChangeMax = (e) => ...
handleChangeMin = (e) => ...
render() {
return (
<div>
Max <TemperatureInput temperature={this.state.max}
onTemperatureChange={this.handleChangeMax} />
Min <TemperatureInput temperature={this.state.min}
onTemperatureChange={this.handleChangeMin} />
</div>
);
}
}
119
@drpicox
High Order Component
function makeThermostat(TemperatureInput) {
return class extends React.Component {
constructor(props) { ... }
handleChangeMax = (e) => ...
handleChangeMin = (e) => ...
render() {
return (
<div>
Max <TemperatureInput temperature={this.state.max}
onTemperatureChange={this.handleChangeMax} />
Min <TemperatureInput temperature={this.state.max}
onTemperatureChange={this.handleChangeMax} />
</div>
);
}
}
} 120
@drpicox
High Order Component
function makeThermostat(TemperatureInput) {
return class extends React.Component {
...
}
}
const ThermostatCelsius =
makeThermostat(TemperatureInputCelsius);
const ThermostatFahrenheit =
makeThermostat(TemperatureInputFahrenheit);
const ThermostatKelvin =
makeThermostat(TemperatureInputKelvin); 121
@drpicox
Debug: displayName
function makeTemperatureInpu(
toKelvin, toFahrenheit, scaleName
) {
class TemperatureInput extends React.Component {
...
}
TemperatureInput.displayName =
`TemperatureInput(${scaleName})`;
return TemperatureInput;
}
122
@drpicox
Debug: displayName
function makeThermostat(TemperatureInput) {
class Thermostat extends React.Component {
...
}
Thermostat.displayName =
`Thermostat(${getDisplayName(TemperatureInput)})`;
return Thermostat;
}
123
@drpicox
Warning
// DON'T use HOCs in render functions!
function App() {
const TemperatureInputAbc =
makeTemperatureInput(a, b, c);
return <TemperatureInputAbc />;
}
class App extends React.Component {
render() {
const TemperatureInputAbc =
makeTemperatureInput(a, b, c);
return <TemperatureInputAbc />;
}
}
124
@drpicox
More in docs
• Use HOCs For Cross-Cutting Concerns
• Don't Mutate the Original Component. 

Use Composition.
• Convention: Pass Unrelated Props Through to the Wrapped
Component
• Convention: Maximizing Composability
• Convention: Wrap the Display Name for Easy Debugging
• Caveats
125
Containers
https://medium.com/@dan_abramov/smart-and-dumb-
components-7ca2f9a7c7d0
@drpicox
Convention
• Types of components
• Routers
• Containers
• Presentational
127
@drpicox
Routes
• Routers
• Decides which component to render
• Create components dynamically
• Usually provided by library
128
@drpicox
Containers
• Knows how to load or mutate data
• Observe Stores
• Dispatch Actions
• Other system interactions
• Always stateful (class notation)
• Renders nothing
• Delegates render to a Presentational Component
• Configures its props
129
@drpicox
Presentational
• Knows how to render things
• Data and callbacks only via props
• does not interact with the application
• Usually functional (not need state)
• Also called Components
130
@drpicox
class Clock extends React.Component {
constructor(props) { ... }
componentDidMount() {
this.timerId = setInterval(
() => this.setState({time: Date.now()}),
1000
);
}
componentWillUnmount() {
clearInterval(this.timerId);
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.time}.</h2>
</div>
);
}
}
131
Presentational
Container
@drpicox
class Clock extends React.Component {
constructor(props) { ... }
componentDidMount() {
this.timerId = setInterval(
() => this.setState({time: Date.now()}),
1000
);
}
componentWillUnmount() {
clearInterval(this.timerId);
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.time}.</h2>
</div>
);
}
}
132
Presentational
Container
@drpicox
Presentational Refactor
function Clock {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.props.time}.</h2>
</div>
);
}
133
@drpicox
Container Refactor
class IntervalClock extends React.Component {
constructor(props) { ... }
componentDidMount() {
this.timerId = setInterval(
() => this.setState({time: Date.now()}),
1000
);
}
componentWillUnmount() {
clearInterval(this.timerId);
}
render() {
return <Clock time={this.state.time} />;
}
}
134

Contenu connexe

Tendances

Android programming -_pushing_the_limits
Android programming -_pushing_the_limitsAndroid programming -_pushing_the_limits
Android programming -_pushing_the_limitsDroidcon Berlin
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Railsrstankov
 
Backbone js
Backbone jsBackbone js
Backbone jsrstankov
 
Getting started with ReactJS
Getting started with ReactJSGetting started with ReactJS
Getting started with ReactJSKrishna Sunuwar
 
React, Redux and es6/7
React, Redux and es6/7React, Redux and es6/7
React, Redux and es6/7Dongho Cho
 
Building a js widget
Building a js widgetBuilding a js widget
Building a js widgetTudor Barbu
 
JavaScript and UI Architecture Best Practices
JavaScript and UI Architecture Best PracticesJavaScript and UI Architecture Best Practices
JavaScript and UI Architecture Best PracticesSiarhei Barysiuk
 
Workshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScriptWorkshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScriptVisual Engineering
 
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KZepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KThomas Fuchs
 
Practical Protocol-Oriented-Programming
Practical Protocol-Oriented-ProgrammingPractical Protocol-Oriented-Programming
Practical Protocol-Oriented-ProgrammingNatasha Murashev
 
"Migrate large gwt applications - Lessons Learned" By Harald Pehl
"Migrate large gwt applications - Lessons Learned" By Harald Pehl"Migrate large gwt applications - Lessons Learned" By Harald Pehl
"Migrate large gwt applications - Lessons Learned" By Harald PehlGWTcon
 
Creating the interfaces of the future with the APIs of today
Creating the interfaces of the future with the APIs of todayCreating the interfaces of the future with the APIs of today
Creating the interfaces of the future with the APIs of todaygerbille
 
How to build to do app using vue composition api and vuex 4 with typescript
How to build to do app using vue composition api and vuex 4 with typescriptHow to build to do app using vue composition api and vuex 4 with typescript
How to build to do app using vue composition api and vuex 4 with typescriptKaty Slemon
 
jQuery 1.7 Events
jQuery 1.7 EventsjQuery 1.7 Events
jQuery 1.7 Eventsdmethvin
 
Understanding Asynchronous JavaScript
Understanding Asynchronous JavaScriptUnderstanding Asynchronous JavaScript
Understanding Asynchronous JavaScriptjnewmanux
 

Tendances (20)

React
React React
React
 
Android programming -_pushing_the_limits
Android programming -_pushing_the_limitsAndroid programming -_pushing_the_limits
Android programming -_pushing_the_limits
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Rails
 
React js
React jsReact js
React js
 
Why ruby
Why rubyWhy ruby
Why ruby
 
Backbone js
Backbone jsBackbone js
Backbone js
 
Getting started with ReactJS
Getting started with ReactJSGetting started with ReactJS
Getting started with ReactJS
 
React, Redux and es6/7
React, Redux and es6/7React, Redux and es6/7
React, Redux and es6/7
 
Building a js widget
Building a js widgetBuilding a js widget
Building a js widget
 
JavaScript and UI Architecture Best Practices
JavaScript and UI Architecture Best PracticesJavaScript and UI Architecture Best Practices
JavaScript and UI Architecture Best Practices
 
Workshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScriptWorkshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScript
 
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KZepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
 
Practical Protocol-Oriented-Programming
Practical Protocol-Oriented-ProgrammingPractical Protocol-Oriented-Programming
Practical Protocol-Oriented-Programming
 
meet.js - QooXDoo
meet.js - QooXDoomeet.js - QooXDoo
meet.js - QooXDoo
 
"Migrate large gwt applications - Lessons Learned" By Harald Pehl
"Migrate large gwt applications - Lessons Learned" By Harald Pehl"Migrate large gwt applications - Lessons Learned" By Harald Pehl
"Migrate large gwt applications - Lessons Learned" By Harald Pehl
 
Creating the interfaces of the future with the APIs of today
Creating the interfaces of the future with the APIs of todayCreating the interfaces of the future with the APIs of today
Creating the interfaces of the future with the APIs of today
 
How to build to do app using vue composition api and vuex 4 with typescript
How to build to do app using vue composition api and vuex 4 with typescriptHow to build to do app using vue composition api and vuex 4 with typescript
How to build to do app using vue composition api and vuex 4 with typescript
 
jQuery 1.7 Events
jQuery 1.7 EventsjQuery 1.7 Events
jQuery 1.7 Events
 
Dan Webb Presentation
Dan Webb PresentationDan Webb Presentation
Dan Webb Presentation
 
Understanding Asynchronous JavaScript
Understanding Asynchronous JavaScriptUnderstanding Asynchronous JavaScript
Understanding Asynchronous JavaScript
 

Similaire à Basic Tutorial of React for Programmers

ReactJS for Programmers
ReactJS for ProgrammersReactJS for Programmers
ReactJS for ProgrammersDavid Rodenas
 
Full Stack React Workshop [CSSC x GDSC]
Full Stack React Workshop [CSSC x GDSC]Full Stack React Workshop [CSSC x GDSC]
Full Stack React Workshop [CSSC x GDSC]GDSC UofT Mississauga
 
Jquery dojo slides
Jquery dojo slidesJquery dojo slides
Jquery dojo slideshelenmga
 
Web Components v1
Web Components v1Web Components v1
Web Components v1Mike Wilcox
 
Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...
Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...
Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...Luciano Mammino
 
React mit TypeScript – eine glückliche Ehe
React mit TypeScript – eine glückliche EheReact mit TypeScript – eine glückliche Ehe
React mit TypeScript – eine glückliche Eheinovex GmbH
 
React Native for multi-platform mobile applications
React Native for multi-platform mobile applicationsReact Native for multi-platform mobile applications
React Native for multi-platform mobile applicationsMatteo Manchi
 
Building Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture ComponentsBuilding Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture ComponentsHassan Abid
 
Web Components With Rails
Web Components With RailsWeb Components With Rails
Web Components With RailsBoris Nadion
 
Lessons from a year of building apps with React Native
Lessons from a year of building apps with React NativeLessons from a year of building apps with React Native
Lessons from a year of building apps with React NativeRyan Boland
 
The Exciting Future Of React
The Exciting Future Of ReactThe Exciting Future Of React
The Exciting Future Of Reactkristijanmkd
 
Red Hat JBoss BRMS and BPMS Workbench and Rich Client Technology
Red Hat JBoss BRMS and BPMS Workbench and Rich Client TechnologyRed Hat JBoss BRMS and BPMS Workbench and Rich Client Technology
Red Hat JBoss BRMS and BPMS Workbench and Rich Client TechnologyMark Proctor
 
The Gist of React Native
The Gist of React NativeThe Gist of React Native
The Gist of React NativeDarren Cruse
 
React - Start learning today
React - Start learning today React - Start learning today
React - Start learning today Nitin Tyagi
 
AFUP Lorraine - Symfony Webpack Encore
AFUP Lorraine - Symfony Webpack EncoreAFUP Lorraine - Symfony Webpack Encore
AFUP Lorraine - Symfony Webpack EncoreEngineor
 
5 x HTML5 worth using in APEX (5)
5 x HTML5 worth using in APEX (5)5 x HTML5 worth using in APEX (5)
5 x HTML5 worth using in APEX (5)Christian Rokitta
 

Similaire à Basic Tutorial of React for Programmers (20)

ReactJS for Programmers
ReactJS for ProgrammersReactJS for Programmers
ReactJS for Programmers
 
Full Stack React Workshop [CSSC x GDSC]
Full Stack React Workshop [CSSC x GDSC]Full Stack React Workshop [CSSC x GDSC]
Full Stack React Workshop [CSSC x GDSC]
 
Jquery dojo slides
Jquery dojo slidesJquery dojo slides
Jquery dojo slides
 
Web Components v1
Web Components v1Web Components v1
Web Components v1
 
Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...
Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...
Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...
 
React mit TypeScript – eine glückliche Ehe
React mit TypeScript – eine glückliche EheReact mit TypeScript – eine glückliche Ehe
React mit TypeScript – eine glückliche Ehe
 
React Native for multi-platform mobile applications
React Native for multi-platform mobile applicationsReact Native for multi-platform mobile applications
React Native for multi-platform mobile applications
 
ReactJS.ppt
ReactJS.pptReactJS.ppt
ReactJS.ppt
 
React js
React jsReact js
React js
 
Building Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture ComponentsBuilding Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture Components
 
Web Components With Rails
Web Components With RailsWeb Components With Rails
Web Components With Rails
 
Lessons from a year of building apps with React Native
Lessons from a year of building apps with React NativeLessons from a year of building apps with React Native
Lessons from a year of building apps with React Native
 
The Exciting Future Of React
The Exciting Future Of ReactThe Exciting Future Of React
The Exciting Future Of React
 
Play!ng with scala
Play!ng with scalaPlay!ng with scala
Play!ng with scala
 
Red Hat JBoss BRMS and BPMS Workbench and Rich Client Technology
Red Hat JBoss BRMS and BPMS Workbench and Rich Client TechnologyRed Hat JBoss BRMS and BPMS Workbench and Rich Client Technology
Red Hat JBoss BRMS and BPMS Workbench and Rich Client Technology
 
The Gist of React Native
The Gist of React NativeThe Gist of React Native
The Gist of React Native
 
React - Start learning today
React - Start learning today React - Start learning today
React - Start learning today
 
AFUP Lorraine - Symfony Webpack Encore
AFUP Lorraine - Symfony Webpack EncoreAFUP Lorraine - Symfony Webpack Encore
AFUP Lorraine - Symfony Webpack Encore
 
Let's react - Meetup
Let's react - MeetupLet's react - Meetup
Let's react - Meetup
 
5 x HTML5 worth using in APEX (5)
5 x HTML5 worth using in APEX (5)5 x HTML5 worth using in APEX (5)
5 x HTML5 worth using in APEX (5)
 

Plus de David Rodenas

TDD CrashCourse Part2: TDD
TDD CrashCourse Part2: TDDTDD CrashCourse Part2: TDD
TDD CrashCourse Part2: TDDDavid Rodenas
 
TDD CrashCourse Part1: Testing
TDD CrashCourse Part1: TestingTDD CrashCourse Part1: Testing
TDD CrashCourse Part1: TestingDavid Rodenas
 
TDD CrashCourse Part3: TDD Techniques
TDD CrashCourse Part3: TDD TechniquesTDD CrashCourse Part3: TDD Techniques
TDD CrashCourse Part3: TDD TechniquesDavid Rodenas
 
TDD CrashCourse Part5: Testing Techniques
TDD CrashCourse Part5: Testing TechniquesTDD CrashCourse Part5: Testing Techniques
TDD CrashCourse Part5: Testing TechniquesDavid Rodenas
 
TDD CrashCourse Part4: Improving Testing
TDD CrashCourse Part4: Improving TestingTDD CrashCourse Part4: Improving Testing
TDD CrashCourse Part4: Improving TestingDavid Rodenas
 
Be professional: We Rule the World
Be professional: We Rule the WorldBe professional: We Rule the World
Be professional: We Rule the WorldDavid Rodenas
 
ES3-2020-P2 Bowling Game Kata
ES3-2020-P2 Bowling Game KataES3-2020-P2 Bowling Game Kata
ES3-2020-P2 Bowling Game KataDavid Rodenas
 
ES3-2020-07 Testing techniques
ES3-2020-07 Testing techniquesES3-2020-07 Testing techniques
ES3-2020-07 Testing techniquesDavid Rodenas
 
ES3-2020-06 Test Driven Development (TDD)
ES3-2020-06 Test Driven Development (TDD)ES3-2020-06 Test Driven Development (TDD)
ES3-2020-06 Test Driven Development (TDD)David Rodenas
 
Testing, Learning and Professionalism — 20171214
Testing, Learning and Professionalism — 20171214Testing, Learning and Professionalism — 20171214
Testing, Learning and Professionalism — 20171214David Rodenas
 
Introduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicoxIntroduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicoxDavid Rodenas
 
From high school to university and work
From high school to university and workFrom high school to university and work
From high school to university and workDavid Rodenas
 
Modules in angular 2.0 beta.1
Modules in angular 2.0 beta.1Modules in angular 2.0 beta.1
Modules in angular 2.0 beta.1David Rodenas
 
Freelance i Enginyeria
Freelance i EnginyeriaFreelance i Enginyeria
Freelance i EnginyeriaDavid Rodenas
 
Angular 1.X Community and API Decissions
Angular 1.X Community and API DecissionsAngular 1.X Community and API Decissions
Angular 1.X Community and API DecissionsDavid Rodenas
 

Plus de David Rodenas (20)

TDD CrashCourse Part2: TDD
TDD CrashCourse Part2: TDDTDD CrashCourse Part2: TDD
TDD CrashCourse Part2: TDD
 
TDD CrashCourse Part1: Testing
TDD CrashCourse Part1: TestingTDD CrashCourse Part1: Testing
TDD CrashCourse Part1: Testing
 
TDD CrashCourse Part3: TDD Techniques
TDD CrashCourse Part3: TDD TechniquesTDD CrashCourse Part3: TDD Techniques
TDD CrashCourse Part3: TDD Techniques
 
TDD CrashCourse Part5: Testing Techniques
TDD CrashCourse Part5: Testing TechniquesTDD CrashCourse Part5: Testing Techniques
TDD CrashCourse Part5: Testing Techniques
 
TDD CrashCourse Part4: Improving Testing
TDD CrashCourse Part4: Improving TestingTDD CrashCourse Part4: Improving Testing
TDD CrashCourse Part4: Improving Testing
 
Be professional: We Rule the World
Be professional: We Rule the WorldBe professional: We Rule the World
Be professional: We Rule the World
 
ES3-2020-P2 Bowling Game Kata
ES3-2020-P2 Bowling Game KataES3-2020-P2 Bowling Game Kata
ES3-2020-P2 Bowling Game Kata
 
ES3-2020-07 Testing techniques
ES3-2020-07 Testing techniquesES3-2020-07 Testing techniques
ES3-2020-07 Testing techniques
 
ES3-2020-06 Test Driven Development (TDD)
ES3-2020-06 Test Driven Development (TDD)ES3-2020-06 Test Driven Development (TDD)
ES3-2020-06 Test Driven Development (TDD)
 
ES3-2020-05 Testing
ES3-2020-05 TestingES3-2020-05 Testing
ES3-2020-05 Testing
 
Testing, Learning and Professionalism — 20171214
Testing, Learning and Professionalism — 20171214Testing, Learning and Professionalism — 20171214
Testing, Learning and Professionalism — 20171214
 
Vespres
VespresVespres
Vespres
 
Faster web pages
Faster web pagesFaster web pages
Faster web pages
 
Introduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicoxIntroduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicox
 
From high school to university and work
From high school to university and workFrom high school to university and work
From high school to university and work
 
Modules in angular 2.0 beta.1
Modules in angular 2.0 beta.1Modules in angular 2.0 beta.1
Modules in angular 2.0 beta.1
 
Freelance i Enginyeria
Freelance i EnginyeriaFreelance i Enginyeria
Freelance i Enginyeria
 
Angular 1.X Community and API Decissions
Angular 1.X Community and API DecissionsAngular 1.X Community and API Decissions
Angular 1.X Community and API Decissions
 
JS and patterns
JS and patternsJS and patterns
JS and patterns
 
MVS: An angular MVC
MVS: An angular MVCMVS: An angular MVC
MVS: An angular MVC
 

Dernier

SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AIABDERRAOUF MEHENNI
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideChristina Lin
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerThousandEyes
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️anilsa9823
 
Project Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationProject Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationkaushalgiri8080
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about usDynamic Netsoft
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...gurkirankumar98700
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfjoe51371421
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 

Dernier (20)

SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
 
Project Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationProject Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanation
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about us
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdf
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 

Basic Tutorial of React for Programmers

  • 4. @drpicox FB about MVC 4 “MVC works pretty well for small applications… but it doesn’t make room for new features.” “Flux is a single direction data flow, that avoids all the arrows going on all directions what makes really hard to understand the system.”
  • 5. @drpicox FB about MVC 5 “Let’s see a real good example: FB chat” “How we get to the point, so we were annoying our users so much the just they wanted us to fix chat?” “The problems here were: • The code has no structure • It was very imperative, that makes it fragile • It loose a lot of the original intend behind it, its hard to tell what it tries [to do] • Add more features only gets this code larger • We had our most annoying chat bug happen over and over • We were always fixing some pretty good edge case, the whole system was fragile • … • This code becomes more fragile with the time. • No member of the team wanted to touch it, they wanted to jump to any other bug.”
  • 7. @drpicox FB about Rendering 7 “Imperative Rendering” “If renders all each time the screen flickers” “We wanted always render all, no matter what” “Here is where React comes in.”
  • 12. @drpicox Hello World <!-- hello-world.html --> <div id="root"></div> // hello-world.js ReactDOM.render( <h1>Hello, world!</h1>, document.getElementById('root') ); 12 https://facebook.github.io/react/docs/hello-world.html
  • 13. @drpicox Hello World // This is translated by Babel to... ReactDOM.render( <h1>Hello, world!</h1>, document.getElementById('root') ); // ...to this ReactDOM.render(React.createElement( 'h1', null, 'Hello, world!' ), document.getElementById('root')); 13 https://babeljs.io/repl
  • 14. @drpicox Do not fear change • ReactJS only updates what changes • Although everything is regenerated every time • Open countdown example at codepen with chrome
 http://codepen.io/drpicox/pen/yMKWGN • Change View > Debug Mode (only works if registered) • Inspect page • You can see that only the span is updated
 (although this crude code changes everything) 14
  • 16. @drpicox JSX // Just sugar syntax const element = <h1>Hello, world!</h1>; // It is just one object const element = React.createElement( "h1", null, "Hello, world!" ); // one object that you can manipulate as object 16
  • 17. @drpicox JSX // May I? console.log(<h1>Hello!</h1>); console.log(<h1>Hello!</h1>.toString()); console.log([<h1>Hello!</h1>]); console.log({hello: <h1>Hello!</h1>}); console.log((() => <h1>Hello!</h1>)()); const salute = (what) => <h1>{what}!</h1>; console.log(salute('Hello')); 17
  • 18. @drpicox JSX // Have multiple elements (but one wrapper) const element = <h1><span>Hello</span>, world!</h1>; // Generates const element = React.createElement( "h1", null, React.createElement( "span", null, "Hello" ), ", world!" ); 18
  • 19. @drpicox JSX // It can be multiline (be careful using return) const element = <h1> Hello, world! </h1>; 19
  • 20. @drpicox JSX // It can be multiline (better) const element = <h1> Hello, world! </h1>; 20
  • 21. @drpicox JSX // It can be multiline (recommended) const element = ( <h1> Hello, world! </h1> ); 21
  • 22. @drpicox JSX // Interpolate any JS expression const user = {name:'bob', lastName:'hoskings'}; const element = ( <h1> Hello, {user.name + ' ' + user.lastName}! </h1> ); // any expression, including JSX const element = <h1>Hello, {<span>world</span>}! 22
  • 23. @drpicox JSX // Add attributes (alias props) const element = <div tabIndex="0">...</div>; // Computed attributes const element = <img src={user.imageUrl} />; // class is className const element = <div className="body">...</div>; 23
  • 24. @drpicox JSX - Cross-site-scripting // It is just a string const title = response.veryMaliciousInput; // This is save const element = <h1>{title}</h1>; 24
  • 25. @drpicox JSX // Is XML-like const element = ( <div> Hello <br/> World </div> ); // Elements must be terminated const element = ( <div> Hello <br> World </div> ); 25
  • 27. @drpicox Rendering Elements // JSX elements are just memory objects const element = <h1>Hello, world</h1>; 27
  • 28. @drpicox Rendering Elements // Given an html DOM element <div id="root"></div> // they can be rendered inside DOM const domElement = document.getElementById('root'); const reactElement = <h1>Hello, world</h1>; ReactDOM.render( reactElement, /* into */ domElement ); 28
  • 29. @drpicox Rendering Elements // As many times as you want // react only updates changes const domElement = document.getElementById('root'); let n = 0; setInterval(() => { ReactDOM.render(<h1>{n += 1}</h1>, domElement); }, 1000); 29
  • 31. @drpicox Component definition // Functional component function Welcome(props) { return <h1>Hello, {props.name}</h1>; } // Class component class Welcome extends React.Component { render() { return <h1>Hello, {this.props.name}</h1>; } } 31
  • 32. @drpicox Render a Component const element = <Welcome name="Dave" />; 32
  • 33. @drpicox Composing Components function App() { return ( <div> <Welcome name="Alice" /> <Welcome name="Bob" /> <Welcome name="Dave" /> </div> ); } 33
  • 34. @drpicox Refactoring Components function Component(props) { return ( <div className="Comment"> <div className="UserInfo"> <img className="Avatar" src={props.author.avatarUrl} alt={props.author.name} /> <div className="UserInfo-name"> {props.author.name} </div> </div> <div className="Comment-text"> {props.text} </div> <div className="Comment-date"> {formatDate(props.date)} </div> </div> ); } 34
  • 35. @drpicox Refactoring Components function Avatar(props) { return ( <img className="Avatar" src={props.user.avatarUrl} alt={props.user.name} /> ); } 35 <img className="Avatar" src={props.author.avatarUrl} alt={props.author.name} />
  • 36. @drpicox Refactoring Components function Component(props) { return ( <div className="Comment"> <div className="UserInfo"> <Avatar user={props.author} /> <div className="UserInfo-name"> {props.author.name} </div> </div> <div className="Comment-text"> {props.text} </div> <div className="Comment-date"> {formatDate(props.date)} </div> </div> ); } 36
  • 37. @drpicox Refactoring Components function Component(props) { return ( <div className="Comment"> <div className="UserInfo"> <Avatar user={props.author} /> <div className="UserInfo-name"> {props.author.name} </div> </div> <div className="Comment-text"> {props.text} </div> <div className="Comment-date"> {formatDate(props.date)} </div> </div> ); } 37
  • 38. @drpicox Refactoring Components function UserInfo(props) { return ( <div className="UserInfo"> <Avatar user={props.user} /> <div className="UserInfo-name"> {props.user.name} </div> </div> ); } 38
  • 39. @drpicox Refactoring Components function Component(props) { return ( <div className="Comment"> <UserInfo user={props.author} /> <div className="Comment-text"> {props.text} </div> <div className="Comment-date"> {formatDate(props.date)} </div> </div> ); } 39
  • 40. @drpicox Props are Read-Only // Render must be read-only function MissbehavingComponent(props) { return <h1>{props.n += 1}</h1>; } 40
  • 42. @drpicox Function to Class Component function Clock(props) { return ( <div> <h1>Hello, world!</h1> <h2>It is {props.time}.</h2> </div> ); } 42
  • 43. @drpicox Function to Class Component class Clock extends React.Component { render() { return ( <div> <h1>Hello, world!</h1> <h2>It is {this.props.time}.</h2> </div> ); } } 43
  • 44. @drpicox Function to Class Component class Clock extends React.Component { render() { return ( <div> <h1>Hello, world!</h1> <h2>It is {this.props.time}.</h2> </div> ); } } 44
  • 45. @drpicox Setup State class Clock extends React.Component { constructor(props) { super(props); this.state = {time: Date.now()}; } render() { ... } } 45
  • 46. @drpicox Setup State class Clock extends React.Component { constructor(props) { ... } render() { return ( <div> <h1>Hello, world!</h1> <h2>It is {this.state.time}.</h2> </div> ); } } 46
  • 47. @drpicox Lifecycle Methods class Clock extends React.Component { constructor(props) { ... } componentDidMount() { /* TODO */ } componentWillUnmount() { /* TODO */ } render() { ... } } 47
  • 48. @drpicox Lifecycle Methods class Clock extends React.Component { constructor(props) { ... } componentDidMount() { this.timerId = setInterval( () => this.setState({time: Date.now()}), 1000 ); } componentWillUnmount() { /* TODO */ } render() { ... } } 48
  • 49. @drpicox Lifecycle Methods class Clock extends React.Component { constructor(props) { ... } componentDidMount() { ... } componentWillUnmount() { clearInterval(this.timerId); } render() { ... } } 49
  • 50. @drpicox setState Asynchronous // Wrong! setState({counter: this.state.counter + 1}); // Correct setState((prevState, props) => ({ counter: prevState.counter + 1 }); 50
  • 51. @drpicox States are Merged constructor() { this.state = {posts: [], users: []}; } componentDidMount() { getPosts((posts) => this.setState({posts})); getUsers((users) => this.setState({users})); } 51
  • 52. @drpicox State Isolated function App() { return ( <div> <Clock /> <Clock /> <Clock /> </div> ); } 52
  • 54. @drpicox onEvent={fn} function ButtonLogHello() { function handleClick() { console.log('The button is clicked'); } return ( <button onClick={handleClick}> click me </button> ); } 54
  • 55. @drpicox onEvent={fn} // It received the event as parameter function ALogHello() { function handleClick(ev) { ev.preventDefault(); console.log('The link is clicked'); } return ( <a href="#" onClick={handleClick}> click me </a> ); } 55
  • 56. @drpicox onEvent={fn} // It can inline functions (are expressions) function DivLogHello() { return ( <button onClick={() => console.log('oh')}> click me </button> ); } 56
  • 57. @drpicox Toggle Example class Toggle extends React.Component { constructor(props) { super(props); this.state = {isToggleOn: true}; // This binding is necessary by `this` this.handleClick = this.handleClick.bind(this); } handleClick() { ... } ... 57 https://facebook.github.io/react/docs/handling-events.html
  • 58. @drpicox Toggle Example class Toggle extends React.Component { constructor(props) { super(props); this.state = {isToggleOn: true}; } handleClick = () => { ... } ... 58 https://facebook.github.io/react/docs/handling-events.html
  • 60. @drpicox Conditional Rendering function UserGreeting(props) { return <h1>Welcome back!</h1>; } function GuestGreeting(props) { return <h1>Please sign up.</h1>; } 60
  • 61. @drpicox By return function Greeting(props) { const isLoggedIn = props.isLoggedIn; if (isLoggedIn) { return <UserGreeting />; } return <GuestGreeting />; } ReactDOM.render( // Try changing to isLoggedIn={true}: <Greeting isLoggedIn={false} />, document.getElementById('root') ); 61
  • 62. @drpicox By variable render() { const isLoggedIn = this.state.isLoggedIn; let button = null; if (isLoggedIn) { button = <LogoutButton onClick={this.handleLogoutClick} />; } else { button = <LoginButton onClick={this.handleLoginClick} />; } return ( <div> <Greeting isLoggedIn={isLoggedIn} /> {button} </div> ); } 62
  • 63. @drpicox By && expression function Mailbox(props) { const unreadMessages = props.unreadMessages; return ( <div> <h1>Hello!</h1> {unreadMessages.length > 0 && <h2> You have {unreadMessages.length} unread messages. </h2> } </div> ); } 63
  • 64. @drpicox By ?: expression render() { const isLoggedIn = this.state.isLoggedIn; return ( <div> {isLoggedIn ? ( <LogoutButton onClick={this.handleLogoutClick} /> ) : ( <LoginButton onClick={this.handleLoginClick} /> )} </div> ); } 64
  • 65. @drpicox Prevent Render function WarningBanner(props) { if (!props.warn) { return null; } return ( <div className="warning"> Warning! </div> ); } 65
  • 67. @drpicox Remember... const numbers = [1, 2, 3, 4, 5]; const doubled = numbers.map((n) => n * 2); console.log(doubled); // [2, 4, 6, 8, 10] 67
  • 68. @drpicox Render Multiple // Render a reactElements array const numbers = [1, 2, 3, 4, 5]; const listItems = numbers.map((number) => <li>{number}</li> ); ReactDOM.render( <ul>{listItems}</ul>, document.getElementById('root') ); 68
  • 69. @drpicox Render Multiple // Refactor into component function NumberList(props) { const numbers = props.numbers; const listItems = numbers.map((number) => <li>{number}</li> ); return ( <ul>{listItems}</ul> ); } const numbers = [1, 2, 3, 4, 5]; ReactDOM.render( <NumberList numbers={numbers} />, document.getElementById('root') ); 69
  • 70. @drpicox Key function NumberList(props) { const numbers = props.numbers; const listItems = numbers.map((number) => <li key={number.toString()}> {number} </li> ); return ( <ul>{listItems}</ul> ); } 70
  • 71. @drpicox Key - index const todoItems = todos.map((todo, index) => // Only do this if items have no stable IDs <li key={index}> {todo.text} </li> ); 71
  • 72. @drpicox Key - Refactor Component function NumberList(props) { const numbers = props.numbers; const listItems = numbers.map((number) => <li key={number.toString()}> {number} </li> ); return ( <ul>{listItems}</ul> ); } 72
  • 73. @drpicox Key - Refactor Component function ListItem(props) { return ( // Wrong! should not be here <li key="props.number.toString()"> {props.number} </li> ); } 73
  • 74. @drpicox Key - Refactor Component function NumberList(props) { const numbers = props.numbers; const listItems = numbers.map((number) => // Correct: key must remain with map <ListItem key={number.toString()} number={number} /> {number} ); return ( <ul>{listItems}</ul> ); } 74
  • 75. @drpicox Key - Uniqueness // Cannot repeat keys in the same list, but... function DoubleList(props) { return ( <div> <NumberList numbers={props.numbers} /> <NumberList numbers={props.numbers} /> <NumberList numbers={props.numbers} /> </div> ); } 75
  • 76. @drpicox .map inside JSX function NumberList(props) { const numbers = props.numbers; return ( <ul> {numbers.map((number) => <ListItem key={number.toString()} value={number} /> )} </ul> ); } 76
  • 77. Forms
  • 78. @drpicox Controlled Components class NameForm extends React.Component { constructor() { ... } handleChange = (event) => { this.setState({value: event.target.value}); } handleSubmit = (event) => { ... } render() { return ( <form onSubmit={this.handleSubmit}> <input type="text" value={this.state.value} onChange={this.handleChange} /> </form> ); } } 78
  • 79. @drpicox Controlled Components class NameForm extends React.Component { constructor(props) { super(props); this.state = {value: ''}; } handleChange = (event) => { ... } handleSubmit = (event) => { ... } render() { ... } } 79
  • 80. @drpicox Controlled Components class NameForm extends React.Component { constructor() { ... } handleChange = (event) => { this.setState({ value: event.target.value.toLowerCase() }); } handleSubmit = (event) => { ... } render() { ... } } 80
  • 83. @drpicox Multiple Inputs <input name="isGoing" type="checkbox" checked={this.state.isGoing} onChange={this.handleInputChange} /> <input name="numberOfGuests" type="number" value={this.state.numberOfGuests} onChange={this.handleInputChange} /> 83
  • 84. @drpicox Multiple Inputs handleInputChange(event) { const target = event.target; const value = target.type === 'checkbox' ? target.checked : target.value; const name = target.name; this.setState({ [name]: value }); } 84
  • 86. @drpicox Synchronizing - Consumer // We want an <input> to generate new values for function BoilingVerdict(props) { if (props.celsius >= 100) { return <p>The water would boil.</p>; } return <p>The water would not boil.</p>; } 86
  • 87. @drpicox Synchronizing - Coordinator class Calculator extends React.Component { constructor(props) { ... } handleChange = (e) => this.setState({temperature: e.target.value}); render() { const temperature = this.state.temperature; return ( <fieldset> <legend>Enter temperature in Celsius:</legend> <input value={temperature} onChange={this.handleChange} /> <BoilingVerdict celsius={parseFloat(temperature)} /> </fieldset> ); } } 87
  • 88. @drpicox Synchronizing - Producer class Calculator extends React.Component { constructor(props) { ... } handleChange = (e) => this.setState({temperature: e.target.value}); render() { const temperature = this.state.temperature; return ( <fieldset> <legend>Enter temperature in Celsius:</legend> <input value={temperature} onChange={this.handleChange} /> <BoilingVerdict celsius={parseFloat(temperature)} /> </fieldset> ); } } 88
  • 89. @drpicox Synchronizing - Producer class TemperatureInput extends React.Component { constructor(props) { ... } handleChange = (e) => this.setState({temperature: e.target.value}); render() { const temperature = this.state.temperature; const scaleName = scaleNames[this.props.scale]; return ( <fieldset> <legend>Enter temperature in {scaleName}:</legend> <input value={temperature} onChange={this.handleChange} /> </fieldset> ); } } 89
  • 90. @drpicox Synchronizing - Producer class Calculator extends React.Component { constructor(props) { ... } handleChange = (e) => this.setState({temperature: ...?}); render() { const temperature = this.state.temperature; return ( <div> <TemperatureInput scale="c" ...? ...? /> <TemperatureInput scale="f" ...? ...? /> <BoilingVerdict celsius={parseFloat(temperature)} /> </div> ); } } 90
  • 91. @drpicox Synchronizing - Producer class TemperatureInput extends React.Component { constructor(props) { ... } handleChange = (e) => this.props.onTemperatureChange(e.target.value); render() { const temperature = this.props.temperature; const scaleName = scaleNames[this.props.scale]; return ( <fieldset> <legend>Enter temperature in {scaleName}:</legend> <input value={temperature} onChange={this.handleChange} /> </fieldset> ); } } 91
  • 92. @drpicox Synchronizing - Coordinator class Calculator extends React.Component { constructor(props) { ... } handleChange = (e) => this.setState({temperature: ...?}); render() { const temperature = this.state.temperature; return ( <div> <TemperatureInput scale="c" ...? ...? /> <TemperatureInput scale="f" ...? ...? /> <BoilingVerdict celsius={parseFloat(temperature)} /> </div> ); } } 92
  • 93. @drpicox Coordinator - Inputs class Calculator extends React.Component { ... render() { const scale = this.state.scale; const temperature = this.state.temperature; const celsius = convertIf(scale === 'f', temperature, toCelsius); const fahrenheit = convertIf(scale === 'c', temperature, toFahrenheit); return ( <div> <TemperatureInput scale="c" temperature={celsius} ...? /> <TemperatureInput scale="f" temperature={fahrenheit} ...? /> <BoilingVerdict celsius={parseFloat(celsius)} /> </div> ); } } 93
  • 94. @drpicox Coordinator Outputs class Calculator extends React.Component { ... handleCelsiusChange = (temperature) => this.setState({scale: 'c', temperature}); handleFahrenheitChange = (temperature) => this.setState({scale: 'f', temperature}); render() { const scale = this.state.scale; const temperature = this.state.temperature; const celsius = convertIf(scale === 'f', temperature, toCelsius); ... <TemperatureInput scale="c" temperature={celsius} onTemperatureChange={this.handleCelsiusChange} /> <TemperatureInput scale="f" temperature={fahrenheit} onTemperatureChange={this.handleFahrenheitChange} /> ... } } 94
  • 95. @drpicox Coordinator Outputs function convertIf(test, temperature, convert) { if (test) { return tryConvert(temperature, convert); } return temperature; } 95
  • 98. @drpicox Java 1.0 98 http://web.mit.edu/java_v1.0.2/www/apibook/javag2.htm An application should override the action method (II-§1.10.1) of the button or of one of its containing windows in order to cause some action to occur. Button + action(...) MyButton + action(...)
  • 99. @drpicox Java 1.1 99 In 1.1,we aimed at solving some major AWT (Abstract Window Toolkit) deficiencies,with a strong focus on quality and performance.The AWT enhancements include [...],a delegation-based event model,[...]. Button + actionActionListener(...) https://www.cs.princeton.edu/courses/archive/fall97/cs461/ jdkdocs/guide/awt/index.html <i> ActionListener + actionPerformed(...) = 0 MyActionListener + actionPerformed(...) *
  • 100. @drpicox Java 1.2 100 When an Action object is added to such a container,the container: Creates a component that is appropriate for that container (a toolbar creates a button component,for example),Gets the appropriate property(s) from the Action object to customize the component (for example, the icon image and flyover text).... <i> Action + actionPerformed(...) = 0 + isEnabled(): bool + setEnabled(b) + getValue(key): Object + putValue(key, value) + addPropertyChangeListener(...) + removePropertyChangeListener(...) http://www.kbs.twi.tudelft.nl/Documentation/Programming/Java/ jdk1.2/api/javax/swing/Action.html
  • 102. @drpicox Children Composition <card> <h1>Welcome</h1> <p> Find here a complete list of all the things that you love. </p> </card> 102
  • 103. @drpicox Children Composition function Card(props) { return ( <div className="card"> {props.children} </div> ); } 103
  • 105. @drpicox Many Children Composition <div class="SplitPane"> <div class="SplitPane-left"> <Contacts /> </div> <div class="SplitPane-left"> <Chat /> </div> </div> 105
  • 106. @drpicox Many Children Composition function SplitPane(props) { return ( <div className="SplitPane"> <div className="SplitPane-left"> {props.left} </div> <div className="SplitPane-right"> {props.right} </div> </div> ); } 106
  • 107. @drpicox Many Children Composition function App() { return ( <SplitPane left={ <Contacts /> } right={ <Chat /> } /> ); } 107
  • 108. @drpicox Specialization function Dialog(props) { return ( <FancyBorder color="blue"> <h1 className="Dialog-title"> {props.title} </h1> <p className="Dialog-message"> {props.message} </p> </FancyBorder> ); } 108
  • 109. @drpicox Specialization function WelcomeDialog(props) { return ( <Dialog title="Welcome" message="Thanks for visiting!" /> ); } 109
  • 110. High Order Components (I) https://facebook.github.io/react/docs/higher-order- components.html
  • 111. @drpicox Like high order functions const safeConvert = (convert) => { return (temperature) => { const input = parseFloat(temperature); if (Number.isNaN(input)) { return ''; } const output = convert(input); const rounded = Math.round(output * 100) / 100; return rounded.toString(); } } 111
  • 112. @drpicox Like high order functions const safeConvert = (convert) => { return (temperature) => { ... } } const safeKelvinToCelsius = safeConvert(kelvinToCelsius); const celsius = safeKelvinToCelsius(kelvin); 112
  • 113. @drpicox Specific Component class TemperatureInputCelsius extends React.Component { handleChange = (e) => this.props.onTemperatureChange( safeCelsiusToKelvin(e.target.value); ); render() { const temperature = this.props.temperature; const celsius = safeKelvinToCelsius(temperature); return ( <fieldset> <legend>Enter temperature in Celsius:</legend> <input value={temperature} onChange={this.handleChange} /> </fieldset> ); } } 113
  • 114. @drpicox Specific Component class TemperatureInputFahrenheit extends React.Component { handleChange = (e) => this.props.onTemperatureChange( safeFahrenheitToKelvin(e.target.value); ); render() { const temperature = this.props.temperature; const celsius = safeKelvinToFahrenheit(temperature); return ( <fieldset> <legend>Enter temperature in Fahrenheit:</legend> <input value={temperature} onChange={this.handleChange} /> </fieldset> ); } } 114
  • 115. @drpicox Generic Component class TemperatureInput? extends React.Component { handleChange = (e) => this.props.onTemperatureChange( toKelvin(e.target.value); ); render() { const temperature = this.props.temperature; const local = toLocal(temperature); return ( <fieldset> <legend>Enter temperature in {scaleName}:</legend> <input value={local} onChange={this.handleChange} /> </fieldset> ); } } 115
  • 116. @drpicox Generic Component function makeTemperatureInput(toKelvin, toLocal, scaleName) { return class extends React.Component { handleChange = (e) => this.props.onTemperatureChange( toKelvin(e.target.value); ); render() { const temperature = this.props.temperature; const local = toLocal(temperature); return ( <fieldset> <legend>Enter temperature in {scaleName}:</legend> <input value={local} onChange={this.handleChange} /> </fieldset> ); } } } 116
  • 117. @drpicox Using Generic Component const TemperatureInputCelsius = makeTemperatureInput( safeCelsiusToKelvin, safeKelvinToCelsius, 'Celsius' ); const TemperatureInputFahrenheit = makeTemperatureInput( safeFahrenheitToKelvin, safeKelvinToFahrenheit, 'Fahrenheit' ); const TemperatureInputKelvin = makeTemperatureInput( identity, identity, 'Kelvin' ); 117
  • 118. @drpicox Using Generic Component const TemperatureInputCelsius = makeTemperatureInput( safeConvert(celsiusToKelvin), safeConvert(kelvinToCelsius), 'Celsius' ); const TemperatureInputFahrenheit = makeTemperatureInput( safeConvert(fahrenheitToKelvin), safeConvert(kelvinToFahrenheit), 'Fahrenheit' ); const TemperatureInputKelvin = makeTemperatureInput( (x) => x, (x) => x, 'Kelvin' ); 118
  • 119. @drpicox High Order Component class Thermostat extends React.Component { constructor(props) { ... } handleChangeMax = (e) => ... handleChangeMin = (e) => ... render() { return ( <div> Max <TemperatureInput temperature={this.state.max} onTemperatureChange={this.handleChangeMax} /> Min <TemperatureInput temperature={this.state.min} onTemperatureChange={this.handleChangeMin} /> </div> ); } } 119
  • 120. @drpicox High Order Component function makeThermostat(TemperatureInput) { return class extends React.Component { constructor(props) { ... } handleChangeMax = (e) => ... handleChangeMin = (e) => ... render() { return ( <div> Max <TemperatureInput temperature={this.state.max} onTemperatureChange={this.handleChangeMax} /> Min <TemperatureInput temperature={this.state.max} onTemperatureChange={this.handleChangeMax} /> </div> ); } } } 120
  • 121. @drpicox High Order Component function makeThermostat(TemperatureInput) { return class extends React.Component { ... } } const ThermostatCelsius = makeThermostat(TemperatureInputCelsius); const ThermostatFahrenheit = makeThermostat(TemperatureInputFahrenheit); const ThermostatKelvin = makeThermostat(TemperatureInputKelvin); 121
  • 122. @drpicox Debug: displayName function makeTemperatureInpu( toKelvin, toFahrenheit, scaleName ) { class TemperatureInput extends React.Component { ... } TemperatureInput.displayName = `TemperatureInput(${scaleName})`; return TemperatureInput; } 122
  • 123. @drpicox Debug: displayName function makeThermostat(TemperatureInput) { class Thermostat extends React.Component { ... } Thermostat.displayName = `Thermostat(${getDisplayName(TemperatureInput)})`; return Thermostat; } 123
  • 124. @drpicox Warning // DON'T use HOCs in render functions! function App() { const TemperatureInputAbc = makeTemperatureInput(a, b, c); return <TemperatureInputAbc />; } class App extends React.Component { render() { const TemperatureInputAbc = makeTemperatureInput(a, b, c); return <TemperatureInputAbc />; } } 124
  • 125. @drpicox More in docs • Use HOCs For Cross-Cutting Concerns • Don't Mutate the Original Component. 
 Use Composition. • Convention: Pass Unrelated Props Through to the Wrapped Component • Convention: Maximizing Composability • Convention: Wrap the Display Name for Easy Debugging • Caveats 125
  • 127. @drpicox Convention • Types of components • Routers • Containers • Presentational 127
  • 128. @drpicox Routes • Routers • Decides which component to render • Create components dynamically • Usually provided by library 128
  • 129. @drpicox Containers • Knows how to load or mutate data • Observe Stores • Dispatch Actions • Other system interactions • Always stateful (class notation) • Renders nothing • Delegates render to a Presentational Component • Configures its props 129
  • 130. @drpicox Presentational • Knows how to render things • Data and callbacks only via props • does not interact with the application • Usually functional (not need state) • Also called Components 130
  • 131. @drpicox class Clock extends React.Component { constructor(props) { ... } componentDidMount() { this.timerId = setInterval( () => this.setState({time: Date.now()}), 1000 ); } componentWillUnmount() { clearInterval(this.timerId); } render() { return ( <div> <h1>Hello, world!</h1> <h2>It is {this.state.time}.</h2> </div> ); } } 131 Presentational Container
  • 132. @drpicox class Clock extends React.Component { constructor(props) { ... } componentDidMount() { this.timerId = setInterval( () => this.setState({time: Date.now()}), 1000 ); } componentWillUnmount() { clearInterval(this.timerId); } render() { return ( <div> <h1>Hello, world!</h1> <h2>It is {this.state.time}.</h2> </div> ); } } 132 Presentational Container
  • 133. @drpicox Presentational Refactor function Clock { return ( <div> <h1>Hello, world!</h1> <h2>It is {this.props.time}.</h2> </div> ); } 133
  • 134. @drpicox Container Refactor class IntervalClock extends React.Component { constructor(props) { ... } componentDidMount() { this.timerId = setInterval( () => this.setState({time: Date.now()}), 1000 ); } componentWillUnmount() { clearInterval(this.timerId); } render() { return <Clock time={this.state.time} />; } } 134