SlideShare a Scribd company logo
React.js Basics
@RobertWPearce
robertwpearce.com/converge-reactjs
robertwpearce.com/converge-reactjs-demo
whoami
From Charleston, SC
Digital Nomad
Work at 100% remote company, Articulate
(articulate.com)
Full-stack dev
Worked with React for almost a year
Why You Should Listen
I've made more small mistakes than you.
Talk Notes
Since requiring/exporting modules and dependencies takes
up too much space, I've omitted them from the
presentation.
don't freak out. This is just a CoffeeScript way of assigning
each of these to variables which represent, for example
Talk Notes
When you see
{div, ul, li, span} = React.DOM
React.DOM.div()
React.DOM.ul()
React.DOM.li()
React.DOM.span()
# etc
This lets you use div, ul, li and span without prefixing them
with React.DOM.___
Talk Notes
There will not be Q&A at the end,
so ask questions as we go.
The Problem
Can't see ConvergeSE's speaker details without navigating
to another page
What We Want
What We Want
vanilla JS or jQuery
We could use data selector finagling to hide/show
information and divs accordingly, but this can get very ugly
and difficult to maintain.
vanilla JS or jQuery
For example, we could
Save each bit of data in data-* attributes for each item
onClick -> Calculate the offset top and height for an item
Give it sufficient padding underneath
Apply the offset top + height to an absolutely positioned
div (100% width) containing the info
Hope things don't explode
Discover that our maths suck when there's already an info
section on the page
Start maintaining state somewhere
vanilla JS or jQuery
or, we could
Determine an item's position on a "row"
onClick -> Insert a DOM element at the end of said row
Populate this DOM element with data obtained from data-
* attributes (or a lookup in a variable via data-id?)
Maintain state of what element is currently clicked
Facepalm when we have to change the # of items per row
"Verba movent, exempla trahunt."
(Words move people, examples compel them.)
— Latin Proverb
First the How
Then the Why
Then the Future
How
Thinking in Components
Thinking in Components
Thinking in Components
Thinking in Components
Speakers
Rows of Speakers (grouped every 4)
Info (conditionally added to a given Row)
Component Structure
Speakers
Row
Speaker
Speaker
Speaker
Speaker
Row
Speaker
Speaker
Speaker
Speaker
Component Structure (selected)
Speakers
Row
Speaker
Speaker
Speaker
Speaker
Row
Speaker
Speaker (selected)
Speaker
Speaker
Info
What do we do first?
Group speakers data in to rows of 4
Map over each row item
Map over each speaker within a row
Proof of Concept (try #1)
# CoffeeScript
speakersData = [{ id: 1, name: 'Emily' }, { id: 2, name: 'Lucy' }]
Speakers = React.createClass
Proof of Concept (try #1)
speakersData = [{ id: 1, name: 'Emily' }, { id: 2, name: 'Lucy' }]
Speakers = React.createClass
render: ->
Proof of Concept (try #1)
speakersData = [{ id: 1, name: 'Emily' }, { id: 2, name: 'Lucy' }]
Speakers = React.createClass
render: ->
rows = _.chunk(speakersData, 4)
Proof of Concept (try #1)
speakersData = [{ id: 1, name: 'Emily' }, { id: 2, name: 'Lucy' }]
Speakers = React.createClass
render: ->
rows = _.chunk(speakersData, 4)
div className: 'speakers',
Proof of Concept (try #1)
speakersData = [{ id: 1, name: 'Emily' }, { id: 2, name: 'Lucy' }]
Speakers = React.createClass
render: ->
rows = _.chunk(speakersData, 4)
div className: 'speakers',
rows.map (row) ->
Proof of Concept (try #1)
speakersData = [{ id: 1, name: 'Emily' }, { id: 2, name: 'Lucy' }]
Speakers = React.createClass
render: ->
rows = _.chunk(speakersData, 4)
div className: 'speakers',
rows.map (row) ->
row.map (speaker) ->
Proof of Concept (try #1)
speakersData = [{ id: 1, name: 'Emily' }, { id: 2, name: 'Lucy' }]
Speakers = React.createClass
render: ->
rows = _.chunk(speakersData, 4)
div className: 'speakers',
rows.map (row) ->
row.map (speaker) ->
div className: 'speaker', speaker.name
Proof of Concept (try #2)
speakersData = [{ id: 1, name: 'Emily' }, { id: 2, name: 'Lucy' }]
Speakers = React.createClass
render: ->
rows = _.chunk(speakersData, 4)
div className: 'speakers',
rows.map (row) ->
row.map (speaker) ->
div className: 'speaker', speaker.name
Proof of Concept (try #2)
speakersData = [{ id: 1, name: 'Emily' }, { id: 2, name: 'Lucy' }]
Speakers = React.createClass
render: ->
rows = _.chunk(speakersData, 4)
div className: 'speakers',
@_buildRows()
_buildRows: ->
rows.map (row) ->
row.map (speaker) ->
div className: 'speaker', speaker.name
Proof of Concept (try #2)
speakersData = [{ id: 1, name: 'Emily' }, { id: 2, name: 'Lucy' }]
Speakers = React.createClass
render: ->
rows = _.chunk(speakersData, 4)
div className: 'speakers',
@_buildRows()
_buildRows: ->
rows.map(@_buildSpeakers)
_buildSpeakers: (row) ->
row.map (speaker) ->
div className: 'speaker', speaker.name
Proof of Concept (try #3)
speakersData = [{ id: 1, name: 'Emily' }, { id: 2, name: 'Lucy' }]
Speakers = React.createClass
render: ->
rows = _.chunk(speakersData, 4)
div className: 'speakers',
rows.map (row) -> Row(row: row)
Row = React.createClass
render: ->
div null, # render must return a React.DOM element or null
@props.row.map (speaker) -> Speaker(speaker: speaker)
Speaker = React.createClass
render: ->
div className: 'speaker', @props.speaker.name
Nice work!
Take a breath.
Asynchronous Data Fetching
Speakers = React.createClass
render: ->
# ...
Speakers = React.createClass
componentWillMount: ->
@_fetchSpeakers()
render: ->
# ...
Speakers = React.createClass
componentWillMount: ->
@_fetchSpeakers()
render: ->
# ...
_fetchSpeakers: ->
SomeAjaxHelper
.get('speakers.json')
.then(@_onSuccess)
_onSuccess: (data) ->
# triggers a re-render
@setState(speakers: data)
Speakers = React.createClass
componentWillMount: ->
@_fetchSpeakers()
render: ->
# what do you think happens here?
rows = _.chunk(@state.speakers, 4)
div className: 'speakers',
rows.map (row) -> Row(row: row)
_fetchSpeakers: ->
# ...
_onSuccess: (data) ->
@setState(speakers: data)
React waits for no code.
Speed is the name of the game.
React calls the render method unless specifically told not to.
When there is no initial state nor inital speakers property,
@state (and thus, speakers) is undefined.
We could do...
Speakers = React.createClass
componentWillMount: ->
@_fetchSpeakers()
render: ->
if @state and @state.speakers and @state.speakers.length > 0
rows = _.chunk(@state.speakers, 4)
div className: 'speakers',
rows.map (row) -> Row(row: row)
else
null
# ...
or we could do...
Speakers = React.createClass
componentWillMount: ->
@_fetchSpeakers()
render: ->
if @state?.speakers?.length > 0
rows = _.chunk(@state.speakers, 4)
div className: 'speakers',
rows.map (row) -> Row(row: row)
else
null
# ...
The Right Way™
Speakers = React.createClass
# With this we now have an initial bit of
# data for our speakers state.
getInitialState: ->
speakers: []
componentWillMount: ->
@_fetchSpeakers()
render: ->
if @state.speakers.length > 0
rows = _.chunk(@state.speakers, 4)
div className: 'speakers',
rows.map (row) -> Row(row: row)
else
null # or a Loader
Building the Child Components
Row Component
Row = React.createClass
render: ->
div null,
@props.row.map (item) =>
Speaker(speaker: item)
Speaker Component
Speaker = React.createClass
render: ->
div className: 'speaker',
img className: 'speaker__image', src: @props.speaker.image
div className: 'speaker__infoBox',
div className: 'speaker__info',
h3 className: 'speaker__name', @props.speaker.name
span null, @props.speaker.work
Adding info toggling functionality
What do we need?
Keep track of currently selected item
Ability to insert the info at the end of a group
Click event that toggles the info for an item
Speakers = React.createClass
getInitialState: ->
speakers: []
selectedId: -1 # or null, if you prefer
render: ->
# ...
rows.map (row) ->
Row(
row: row
selectedId: @state.selectedId
updateSelectedId: @_updateSelectedId
)
_updateSelectedId: (selectedId) ->
@setState(selectedId: selectedId)
Row = React.createClass
render: ->
div null, @_buildRow()
_buildRow: ->
selectedItems = @_filterSelected()
rendered = @props.row.map (item) =>
Speaker(
isSelected: item.id is @props.selectedId
speaker: item
updateSelectedId: @props.updateSelectedId
)
if selectedItems.length > 0
rendered.push(Info(speaker: selectedItems[0]))
rendered
_filterSelected: ->
@props.row.filter (item) =>
item.id is @props.selectedId
Speaker = React.createClass
render: ->
div className: 'speaker', onClick: @_handleToggleClick,
img className: 'speaker__image', src: @props.speaker.image
div className: 'speaker__infoBox',
div className: 'speaker__info',
h3 className: 'speaker__name', @props.speaker.name
span null, @props.speaker.work
# Determines selectedId value and
# triggers the callback function
# passed down from Speakers
_handleToggleClick: ->
# b/c i don't have room for a proper if/else
selectedId = @props.speaker.id
selectedId = -1 if @props.isSelected # reset!
@props.updateSelectedId(selectedId)
Info = React.createClass
render: ->
div className: 'speakerInfo',
h3 null, @props.speaker.name
p null,
div null, @props.speaker.work
div null, @props.speaker.twitter
p null, @props.speaker.bio
Rendering to the DOM
// index.js
var React = require('react');
var Speakers = require('./Speakers.react');
var div = document.createElement('div');
document.body.insertBefore(div, document.body.firstChild);
React.render(Speakers(), div);
// | |
// component container
Ship It and Pray...
We won't go in to this, but it now is easy to add additional
functionality, such as Search.
Speakers = React.createClass
# ...
render: ->
div null,
Search()
@_renderRows()
and control the data via this main component.
Take a breath.
Why
Truth
Maintaining state in web applications. How...?
In web applications, what has been the source of data truth
since day one?
The server.
Mutating the DOM never made sense to me.
The solution?
Isn't that expensive on browsers?
Nope.
Virtual DOM
Image credit: Steven Hollidge
Re-rendering subset (good)
Image credit: Christopher Chedeau
Re-rendering subset (good)
Image credit: Christopher Chedeau
but...
Image credit: Alexander Early
The previous image occurs when one component does not
control all of the data for an application, or at least for a set
of subcomponents.
It's very tempting to want to manage state inside the
component that the state affects.
Remember this?
Speaker = React.createClass
render: ->
# ...
Row(updateSelectedId: @_updateSelectedId)
_updateSelectedId: (selectedId) ->
# ...
Row = React.createClass
render: ->
# ...
Speaker(updateSelectedId: @_updateSelectedId)
Speaker = React.createClass
render: ->
# ...
div className: 'speaker', onClick: @_handleClick
# ...
_handleClick: ->
# ...
@props.updateSelectedId(selectedId)
Utilizing Events
Speaker = React.createClass
componentDidMount: ->
SpeakerEmitter.addSelectionChangeListener(@_updateSelectedId)
componentWillUnmount: ->
SpeakerEmitter.removeSelectionChangeListener(@_updateSelectedId)
render: ->
Row()
_updateSelectedId: (selectedId) ->
# ...
Row = React.createClass
render: ->
Speaker()
Speaker = React.createClass
render: ->
div className: 'speaker', onClick: @_handleClick
_handleClick: ->
SpeakerEmitter.emitSelectionChange(selectedId)
Image credit: Alexander Early
The Future
It's quite popular
Client Side & Server-side
You can compile React on the server and use the same
templates for server-side rendering as you do for client-side.
It's gone native
They're Open Source Committed
TL;DR
If your current JS framework/lib/stack makes you feel like
give React a shot and see if if makes you feel like

More Related Content

What's hot

Object Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOPObject Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOP
Wildan Maulana
 
How to Become a Tree Hugger: Random Forests and Predictive Modeling for Devel...
How to Become a Tree Hugger: Random Forests and Predictive Modeling for Devel...How to Become a Tree Hugger: Random Forests and Predictive Modeling for Devel...
How to Become a Tree Hugger: Random Forests and Predictive Modeling for Devel...
Matt Harrison
 
SOLID Ruby, SOLID Rails
SOLID Ruby, SOLID RailsSOLID Ruby, SOLID Rails
SOLID Ruby, SOLID Rails
Jens-Christian Fischer
 
Python programming : Inheritance and polymorphism
Python programming : Inheritance and polymorphismPython programming : Inheritance and polymorphism
Python programming : Inheritance and polymorphism
Emertxe Information Technologies Pvt Ltd
 
Banishing Loops with Functional Programming in PHP
Banishing Loops with Functional Programming in PHPBanishing Loops with Functional Programming in PHP
Banishing Loops with Functional Programming in PHP
David Hayes
 
Analysis of Fatal Utah Avalanches with Python. From Scraping, Analysis, to In...
Analysis of Fatal Utah Avalanches with Python. From Scraping, Analysis, to In...Analysis of Fatal Utah Avalanches with Python. From Scraping, Analysis, to In...
Analysis of Fatal Utah Avalanches with Python. From Scraping, Analysis, to In...
Matt Harrison
 
Class and Objects in PHP
Class and Objects in PHPClass and Objects in PHP
Class and Objects in PHP
Ramasubbu .P
 
Object Oriented PHP5
Object Oriented PHP5Object Oriented PHP5
Object Oriented PHP5
Jason Austin
 
Database API, your new friend
Database API, your new friendDatabase API, your new friend
Database API, your new friend
kikoalonsob
 
The Query the Whole Query and Nothing but the Query
The Query the Whole Query and Nothing but the QueryThe Query the Whole Query and Nothing but the Query
The Query the Whole Query and Nothing but the Query
Chris Olbekson
 
Separation of concerns - DPC12
Separation of concerns - DPC12Separation of concerns - DPC12
Separation of concerns - DPC12
Stephan Hochdörfer
 
PHP Unit 4 arrays
PHP Unit 4 arraysPHP Unit 4 arrays
PHP Unit 4 arrays
Kumar
 
Your code sucks, let's fix it
Your code sucks, let's fix itYour code sucks, let's fix it
Your code sucks, let's fix it
Rafael Dohms
 
Codeware
CodewareCodeware
Codeware
Uri Nativ
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
Michelangelo van Dam
 
Writing Apps the Google-y Way (Brisbane)
Writing Apps the Google-y Way (Brisbane)Writing Apps the Google-y Way (Brisbane)
Writing Apps the Google-y Way (Brisbane)
Pamela Fox
 
GDI Seattle - Intro to JavaScript Class 2
GDI Seattle - Intro to JavaScript Class 2GDI Seattle - Intro to JavaScript Class 2
GDI Seattle - Intro to JavaScript Class 2
Heather Rock
 
جلسه هفتم پایتون برای هکر های قانونی دوره مقدماتی پاییز ۹۲
جلسه هفتم پایتون برای هکر های قانونی دوره مقدماتی پاییز ۹۲جلسه هفتم پایتون برای هکر های قانونی دوره مقدماتی پاییز ۹۲
جلسه هفتم پایتون برای هکر های قانونی دوره مقدماتی پاییز ۹۲
Mohammad Reza Kamalifard
 
CakeFest 2013 keynote
CakeFest 2013 keynoteCakeFest 2013 keynote
CakeFest 2013 keynote
José Lorenzo Rodríguez Urdaneta
 
Drupal7 dbtng
Drupal7  dbtngDrupal7  dbtng
Drupal7 dbtng
Nicolas Leroy
 

What's hot (20)

Object Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOPObject Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOP
 
How to Become a Tree Hugger: Random Forests and Predictive Modeling for Devel...
How to Become a Tree Hugger: Random Forests and Predictive Modeling for Devel...How to Become a Tree Hugger: Random Forests and Predictive Modeling for Devel...
How to Become a Tree Hugger: Random Forests and Predictive Modeling for Devel...
 
SOLID Ruby, SOLID Rails
SOLID Ruby, SOLID RailsSOLID Ruby, SOLID Rails
SOLID Ruby, SOLID Rails
 
Python programming : Inheritance and polymorphism
Python programming : Inheritance and polymorphismPython programming : Inheritance and polymorphism
Python programming : Inheritance and polymorphism
 
Banishing Loops with Functional Programming in PHP
Banishing Loops with Functional Programming in PHPBanishing Loops with Functional Programming in PHP
Banishing Loops with Functional Programming in PHP
 
Analysis of Fatal Utah Avalanches with Python. From Scraping, Analysis, to In...
Analysis of Fatal Utah Avalanches with Python. From Scraping, Analysis, to In...Analysis of Fatal Utah Avalanches with Python. From Scraping, Analysis, to In...
Analysis of Fatal Utah Avalanches with Python. From Scraping, Analysis, to In...
 
Class and Objects in PHP
Class and Objects in PHPClass and Objects in PHP
Class and Objects in PHP
 
Object Oriented PHP5
Object Oriented PHP5Object Oriented PHP5
Object Oriented PHP5
 
Database API, your new friend
Database API, your new friendDatabase API, your new friend
Database API, your new friend
 
The Query the Whole Query and Nothing but the Query
The Query the Whole Query and Nothing but the QueryThe Query the Whole Query and Nothing but the Query
The Query the Whole Query and Nothing but the Query
 
Separation of concerns - DPC12
Separation of concerns - DPC12Separation of concerns - DPC12
Separation of concerns - DPC12
 
PHP Unit 4 arrays
PHP Unit 4 arraysPHP Unit 4 arrays
PHP Unit 4 arrays
 
Your code sucks, let's fix it
Your code sucks, let's fix itYour code sucks, let's fix it
Your code sucks, let's fix it
 
Codeware
CodewareCodeware
Codeware
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
 
Writing Apps the Google-y Way (Brisbane)
Writing Apps the Google-y Way (Brisbane)Writing Apps the Google-y Way (Brisbane)
Writing Apps the Google-y Way (Brisbane)
 
GDI Seattle - Intro to JavaScript Class 2
GDI Seattle - Intro to JavaScript Class 2GDI Seattle - Intro to JavaScript Class 2
GDI Seattle - Intro to JavaScript Class 2
 
جلسه هفتم پایتون برای هکر های قانونی دوره مقدماتی پاییز ۹۲
جلسه هفتم پایتون برای هکر های قانونی دوره مقدماتی پاییز ۹۲جلسه هفتم پایتون برای هکر های قانونی دوره مقدماتی پاییز ۹۲
جلسه هفتم پایتون برای هکر های قانونی دوره مقدماتی پاییز ۹۲
 
CakeFest 2013 keynote
CakeFest 2013 keynoteCakeFest 2013 keynote
CakeFest 2013 keynote
 
Drupal7 dbtng
Drupal7  dbtngDrupal7  dbtng
Drupal7 dbtng
 

Similar to React.js Basics - ConvergeSE 2015

pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
Postobjektové programovanie v Ruby
Postobjektové programovanie v RubyPostobjektové programovanie v Ruby
Postobjektové programovanie v Ruby
Jano Suchal
 
Sequel
SequelSequel
Desarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosDesarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutos
Edgar Suarez
 
Scala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghScala @ TechMeetup Edinburgh
Scala @ TechMeetup Edinburgh
Stuart Roebuck
 
DataMapper
DataMapperDataMapper
DataMapper
Yehuda Katz
 
Practical cats
Practical catsPractical cats
Practical cats
Raymond Tay
 
Building a friendly .NET SDK to connect to Space
Building a friendly .NET SDK to connect to SpaceBuilding a friendly .NET SDK to connect to Space
Building a friendly .NET SDK to connect to Space
Maarten Balliauw
 
Rich Internet Applications con JavaFX e NetBeans
Rich Internet Applications  con JavaFX e NetBeans Rich Internet Applications  con JavaFX e NetBeans
Rich Internet Applications con JavaFX e NetBeans
Fabrizio Giudici
 
Structuring React.js Components
Structuring React.js ComponentsStructuring React.js Components
Structuring React.js Components
Bartek Witczak
 
4Developers 2018: Structuring React components (Bartłomiej Witczak)
4Developers 2018: Structuring React components (Bartłomiej Witczak)4Developers 2018: Structuring React components (Bartłomiej Witczak)
4Developers 2018: Structuring React components (Bartłomiej Witczak)
PROIDEA
 
ZendCon2010 The Doctrine Project
ZendCon2010 The Doctrine ProjectZendCon2010 The Doctrine Project
ZendCon2010 The Doctrine Project
Jonathan Wage
 
Angular Schematics
Angular SchematicsAngular Schematics
Angular Schematics
Christoffer Noring
 
INFORMATIVE ESSAYThe purpose of the Informative Essay assignme.docx
INFORMATIVE ESSAYThe purpose of the Informative Essay assignme.docxINFORMATIVE ESSAYThe purpose of the Informative Essay assignme.docx
INFORMATIVE ESSAYThe purpose of the Informative Essay assignme.docx
carliotwaycave
 
Extreme Swift
Extreme SwiftExtreme Swift
Extreme Swift
Movel
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
Dmitry Buzdin
 
Using Task Queues and D3.js to build an analytics product on App Engine
Using Task Queues and D3.js to build an analytics product on App EngineUsing Task Queues and D3.js to build an analytics product on App Engine
Using Task Queues and D3.js to build an analytics product on App Engine
River of Talent
 

Similar to React.js Basics - ConvergeSE 2015 (20)

pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
Postobjektové programovanie v Ruby
Postobjektové programovanie v RubyPostobjektové programovanie v Ruby
Postobjektové programovanie v Ruby
 
Sequel
SequelSequel
Sequel
 
Desarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosDesarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutos
 
Scala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghScala @ TechMeetup Edinburgh
Scala @ TechMeetup Edinburgh
 
DataMapper
DataMapperDataMapper
DataMapper
 
Practical cats
Practical catsPractical cats
Practical cats
 
Building a friendly .NET SDK to connect to Space
Building a friendly .NET SDK to connect to SpaceBuilding a friendly .NET SDK to connect to Space
Building a friendly .NET SDK to connect to Space
 
Rich Internet Applications con JavaFX e NetBeans
Rich Internet Applications  con JavaFX e NetBeans Rich Internet Applications  con JavaFX e NetBeans
Rich Internet Applications con JavaFX e NetBeans
 
Structuring React.js Components
Structuring React.js ComponentsStructuring React.js Components
Structuring React.js Components
 
4Developers 2018: Structuring React components (Bartłomiej Witczak)
4Developers 2018: Structuring React components (Bartłomiej Witczak)4Developers 2018: Structuring React components (Bartłomiej Witczak)
4Developers 2018: Structuring React components (Bartłomiej Witczak)
 
ZendCon2010 The Doctrine Project
ZendCon2010 The Doctrine ProjectZendCon2010 The Doctrine Project
ZendCon2010 The Doctrine Project
 
Angular Schematics
Angular SchematicsAngular Schematics
Angular Schematics
 
INFORMATIVE ESSAYThe purpose of the Informative Essay assignme.docx
INFORMATIVE ESSAYThe purpose of the Informative Essay assignme.docxINFORMATIVE ESSAYThe purpose of the Informative Essay assignme.docx
INFORMATIVE ESSAYThe purpose of the Informative Essay assignme.docx
 
Extreme Swift
Extreme SwiftExtreme Swift
Extreme Swift
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
Using Task Queues and D3.js to build an analytics product on App Engine
Using Task Queues and D3.js to build an analytics product on App EngineUsing Task Queues and D3.js to build an analytics product on App Engine
Using Task Queues and D3.js to build an analytics product on App Engine
 

More from Robert Pearce

How to Lose Functional Programming at Work
How to Lose Functional Programming at WorkHow to Lose Functional Programming at Work
How to Lose Functional Programming at Work
Robert Pearce
 
Some Functional Programming in JavaScript and Ramda.js
Some Functional Programming in JavaScript and Ramda.jsSome Functional Programming in JavaScript and Ramda.js
Some Functional Programming in JavaScript and Ramda.js
Robert Pearce
 
A Path to Point-Free JavaScript
A Path to Point-Free JavaScriptA Path to Point-Free JavaScript
A Path to Point-Free JavaScript
Robert Pearce
 
From Promises & async/await to Async Algebraic Data Types
From Promises & async/await to Async Algebraic Data TypesFrom Promises & async/await to Async Algebraic Data Types
From Promises & async/await to Async Algebraic Data Types
Robert Pearce
 
hakyll – haskell static site generator
hakyll – haskell static site generatorhakyll – haskell static site generator
hakyll – haskell static site generator
Robert Pearce
 
FP in JS-Land
FP in JS-LandFP in JS-Land
FP in JS-Land
Robert Pearce
 
Behaviour & Your Team
Behaviour & Your TeamBehaviour & Your Team
Behaviour & Your Team
Robert Pearce
 
Static sites with react
Static sites with reactStatic sites with react
Static sites with react
Robert Pearce
 
JavaScript 101 - Class 2
JavaScript 101 - Class 2JavaScript 101 - Class 2
JavaScript 101 - Class 2
Robert Pearce
 
JavaScript 101 - Class 1
JavaScript 101 - Class 1JavaScript 101 - Class 1
JavaScript 101 - Class 1
Robert Pearce
 

More from Robert Pearce (10)

How to Lose Functional Programming at Work
How to Lose Functional Programming at WorkHow to Lose Functional Programming at Work
How to Lose Functional Programming at Work
 
Some Functional Programming in JavaScript and Ramda.js
Some Functional Programming in JavaScript and Ramda.jsSome Functional Programming in JavaScript and Ramda.js
Some Functional Programming in JavaScript and Ramda.js
 
A Path to Point-Free JavaScript
A Path to Point-Free JavaScriptA Path to Point-Free JavaScript
A Path to Point-Free JavaScript
 
From Promises & async/await to Async Algebraic Data Types
From Promises & async/await to Async Algebraic Data TypesFrom Promises & async/await to Async Algebraic Data Types
From Promises & async/await to Async Algebraic Data Types
 
hakyll – haskell static site generator
hakyll – haskell static site generatorhakyll – haskell static site generator
hakyll – haskell static site generator
 
FP in JS-Land
FP in JS-LandFP in JS-Land
FP in JS-Land
 
Behaviour & Your Team
Behaviour & Your TeamBehaviour & Your Team
Behaviour & Your Team
 
Static sites with react
Static sites with reactStatic sites with react
Static sites with react
 
JavaScript 101 - Class 2
JavaScript 101 - Class 2JavaScript 101 - Class 2
JavaScript 101 - Class 2
 
JavaScript 101 - Class 1
JavaScript 101 - Class 1JavaScript 101 - Class 1
JavaScript 101 - Class 1
 

Recently uploaded

Nordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptxNordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptx
MichaelKnudsen27
 
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development ProvidersYour One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
akankshawande
 
Energy Efficient Video Encoding for Cloud and Edge Computing Instances
Energy Efficient Video Encoding for Cloud and Edge Computing InstancesEnergy Efficient Video Encoding for Cloud and Edge Computing Instances
Energy Efficient Video Encoding for Cloud and Edge Computing Instances
Alpen-Adria-Universität
 
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Jeffrey Haguewood
 
dbms calicut university B. sc Cs 4th sem.pdf
dbms  calicut university B. sc Cs 4th sem.pdfdbms  calicut university B. sc Cs 4th sem.pdf
dbms calicut university B. sc Cs 4th sem.pdf
Shinana2
 
Operating System Used by Users in day-to-day life.pptx
Operating System Used by Users in day-to-day life.pptxOperating System Used by Users in day-to-day life.pptx
Operating System Used by Users in day-to-day life.pptx
Pravash Chandra Das
 
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdfMonitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Tosin Akinosho
 
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
saastr
 
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy SurveyTrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc
 
System Design Case Study: Building a Scalable E-Commerce Platform - Hiike
System Design Case Study: Building a Scalable E-Commerce Platform - HiikeSystem Design Case Study: Building a Scalable E-Commerce Platform - Hiike
System Design Case Study: Building a Scalable E-Commerce Platform - Hiike
Hiike
 
Finale of the Year: Apply for Next One!
Finale of the Year: Apply for Next One!Finale of the Year: Apply for Next One!
Finale of the Year: Apply for Next One!
GDSC PJATK
 
Nunit vs XUnit vs MSTest Differences Between These Unit Testing Frameworks.pdf
Nunit vs XUnit vs MSTest Differences Between These Unit Testing Frameworks.pdfNunit vs XUnit vs MSTest Differences Between These Unit Testing Frameworks.pdf
Nunit vs XUnit vs MSTest Differences Between These Unit Testing Frameworks.pdf
flufftailshop
 
Generating privacy-protected synthetic data using Secludy and Milvus
Generating privacy-protected synthetic data using Secludy and MilvusGenerating privacy-protected synthetic data using Secludy and Milvus
Generating privacy-protected synthetic data using Secludy and Milvus
Zilliz
 
Introduction of Cybersecurity with OSS at Code Europe 2024
Introduction of Cybersecurity with OSS  at Code Europe 2024Introduction of Cybersecurity with OSS  at Code Europe 2024
Introduction of Cybersecurity with OSS at Code Europe 2024
Hiroshi SHIBATA
 
June Patch Tuesday
June Patch TuesdayJune Patch Tuesday
June Patch Tuesday
Ivanti
 
Serial Arm Control in Real Time Presentation
Serial Arm Control in Real Time PresentationSerial Arm Control in Real Time Presentation
Serial Arm Control in Real Time Presentation
tolgahangng
 
Deep Dive: Getting Funded with Jason Jason Lemkin Founder & CEO @ SaaStr
Deep Dive: Getting Funded with Jason Jason Lemkin Founder & CEO @ SaaStrDeep Dive: Getting Funded with Jason Jason Lemkin Founder & CEO @ SaaStr
Deep Dive: Getting Funded with Jason Jason Lemkin Founder & CEO @ SaaStr
saastr
 
Fueling AI with Great Data with Airbyte Webinar
Fueling AI with Great Data with Airbyte WebinarFueling AI with Great Data with Airbyte Webinar
Fueling AI with Great Data with Airbyte Webinar
Zilliz
 
UI5 Controls simplified - UI5con2024 presentation
UI5 Controls simplified - UI5con2024 presentationUI5 Controls simplified - UI5con2024 presentation
UI5 Controls simplified - UI5con2024 presentation
Wouter Lemaire
 
Digital Marketing Trends in 2024 | Guide for Staying Ahead
Digital Marketing Trends in 2024 | Guide for Staying AheadDigital Marketing Trends in 2024 | Guide for Staying Ahead
Digital Marketing Trends in 2024 | Guide for Staying Ahead
Wask
 

Recently uploaded (20)

Nordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptxNordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptx
 
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development ProvidersYour One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
 
Energy Efficient Video Encoding for Cloud and Edge Computing Instances
Energy Efficient Video Encoding for Cloud and Edge Computing InstancesEnergy Efficient Video Encoding for Cloud and Edge Computing Instances
Energy Efficient Video Encoding for Cloud and Edge Computing Instances
 
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
 
dbms calicut university B. sc Cs 4th sem.pdf
dbms  calicut university B. sc Cs 4th sem.pdfdbms  calicut university B. sc Cs 4th sem.pdf
dbms calicut university B. sc Cs 4th sem.pdf
 
Operating System Used by Users in day-to-day life.pptx
Operating System Used by Users in day-to-day life.pptxOperating System Used by Users in day-to-day life.pptx
Operating System Used by Users in day-to-day life.pptx
 
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdfMonitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdf
 
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
 
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy SurveyTrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy Survey
 
System Design Case Study: Building a Scalable E-Commerce Platform - Hiike
System Design Case Study: Building a Scalable E-Commerce Platform - HiikeSystem Design Case Study: Building a Scalable E-Commerce Platform - Hiike
System Design Case Study: Building a Scalable E-Commerce Platform - Hiike
 
Finale of the Year: Apply for Next One!
Finale of the Year: Apply for Next One!Finale of the Year: Apply for Next One!
Finale of the Year: Apply for Next One!
 
Nunit vs XUnit vs MSTest Differences Between These Unit Testing Frameworks.pdf
Nunit vs XUnit vs MSTest Differences Between These Unit Testing Frameworks.pdfNunit vs XUnit vs MSTest Differences Between These Unit Testing Frameworks.pdf
Nunit vs XUnit vs MSTest Differences Between These Unit Testing Frameworks.pdf
 
Generating privacy-protected synthetic data using Secludy and Milvus
Generating privacy-protected synthetic data using Secludy and MilvusGenerating privacy-protected synthetic data using Secludy and Milvus
Generating privacy-protected synthetic data using Secludy and Milvus
 
Introduction of Cybersecurity with OSS at Code Europe 2024
Introduction of Cybersecurity with OSS  at Code Europe 2024Introduction of Cybersecurity with OSS  at Code Europe 2024
Introduction of Cybersecurity with OSS at Code Europe 2024
 
June Patch Tuesday
June Patch TuesdayJune Patch Tuesday
June Patch Tuesday
 
Serial Arm Control in Real Time Presentation
Serial Arm Control in Real Time PresentationSerial Arm Control in Real Time Presentation
Serial Arm Control in Real Time Presentation
 
Deep Dive: Getting Funded with Jason Jason Lemkin Founder & CEO @ SaaStr
Deep Dive: Getting Funded with Jason Jason Lemkin Founder & CEO @ SaaStrDeep Dive: Getting Funded with Jason Jason Lemkin Founder & CEO @ SaaStr
Deep Dive: Getting Funded with Jason Jason Lemkin Founder & CEO @ SaaStr
 
Fueling AI with Great Data with Airbyte Webinar
Fueling AI with Great Data with Airbyte WebinarFueling AI with Great Data with Airbyte Webinar
Fueling AI with Great Data with Airbyte Webinar
 
UI5 Controls simplified - UI5con2024 presentation
UI5 Controls simplified - UI5con2024 presentationUI5 Controls simplified - UI5con2024 presentation
UI5 Controls simplified - UI5con2024 presentation
 
Digital Marketing Trends in 2024 | Guide for Staying Ahead
Digital Marketing Trends in 2024 | Guide for Staying AheadDigital Marketing Trends in 2024 | Guide for Staying Ahead
Digital Marketing Trends in 2024 | Guide for Staying Ahead
 

React.js Basics - ConvergeSE 2015

  • 2. whoami From Charleston, SC Digital Nomad Work at 100% remote company, Articulate (articulate.com) Full-stack dev Worked with React for almost a year
  • 3. Why You Should Listen I've made more small mistakes than you.
  • 4. Talk Notes Since requiring/exporting modules and dependencies takes up too much space, I've omitted them from the presentation.
  • 5. don't freak out. This is just a CoffeeScript way of assigning each of these to variables which represent, for example Talk Notes When you see {div, ul, li, span} = React.DOM React.DOM.div() React.DOM.ul() React.DOM.li() React.DOM.span() # etc This lets you use div, ul, li and span without prefixing them with React.DOM.___
  • 6. Talk Notes There will not be Q&A at the end, so ask questions as we go.
  • 7. The Problem Can't see ConvergeSE's speaker details without navigating to another page
  • 8.
  • 9.
  • 11.
  • 13. vanilla JS or jQuery We could use data selector finagling to hide/show information and divs accordingly, but this can get very ugly and difficult to maintain.
  • 14. vanilla JS or jQuery For example, we could Save each bit of data in data-* attributes for each item onClick -> Calculate the offset top and height for an item Give it sufficient padding underneath Apply the offset top + height to an absolutely positioned div (100% width) containing the info Hope things don't explode Discover that our maths suck when there's already an info section on the page Start maintaining state somewhere
  • 15. vanilla JS or jQuery or, we could Determine an item's position on a "row" onClick -> Insert a DOM element at the end of said row Populate this DOM element with data obtained from data- * attributes (or a lookup in a variable via data-id?) Maintain state of what element is currently clicked Facepalm when we have to change the # of items per row
  • 16. "Verba movent, exempla trahunt." (Words move people, examples compel them.) — Latin Proverb
  • 17. First the How Then the Why Then the Future
  • 18. How
  • 23. Speakers Rows of Speakers (grouped every 4) Info (conditionally added to a given Row)
  • 26. What do we do first? Group speakers data in to rows of 4 Map over each row item Map over each speaker within a row
  • 27. Proof of Concept (try #1) # CoffeeScript speakersData = [{ id: 1, name: 'Emily' }, { id: 2, name: 'Lucy' }] Speakers = React.createClass
  • 28. Proof of Concept (try #1) speakersData = [{ id: 1, name: 'Emily' }, { id: 2, name: 'Lucy' }] Speakers = React.createClass render: ->
  • 29. Proof of Concept (try #1) speakersData = [{ id: 1, name: 'Emily' }, { id: 2, name: 'Lucy' }] Speakers = React.createClass render: -> rows = _.chunk(speakersData, 4)
  • 30. Proof of Concept (try #1) speakersData = [{ id: 1, name: 'Emily' }, { id: 2, name: 'Lucy' }] Speakers = React.createClass render: -> rows = _.chunk(speakersData, 4) div className: 'speakers',
  • 31. Proof of Concept (try #1) speakersData = [{ id: 1, name: 'Emily' }, { id: 2, name: 'Lucy' }] Speakers = React.createClass render: -> rows = _.chunk(speakersData, 4) div className: 'speakers', rows.map (row) ->
  • 32. Proof of Concept (try #1) speakersData = [{ id: 1, name: 'Emily' }, { id: 2, name: 'Lucy' }] Speakers = React.createClass render: -> rows = _.chunk(speakersData, 4) div className: 'speakers', rows.map (row) -> row.map (speaker) ->
  • 33. Proof of Concept (try #1) speakersData = [{ id: 1, name: 'Emily' }, { id: 2, name: 'Lucy' }] Speakers = React.createClass render: -> rows = _.chunk(speakersData, 4) div className: 'speakers', rows.map (row) -> row.map (speaker) -> div className: 'speaker', speaker.name
  • 34.
  • 35. Proof of Concept (try #2) speakersData = [{ id: 1, name: 'Emily' }, { id: 2, name: 'Lucy' }] Speakers = React.createClass render: -> rows = _.chunk(speakersData, 4) div className: 'speakers', rows.map (row) -> row.map (speaker) -> div className: 'speaker', speaker.name
  • 36. Proof of Concept (try #2) speakersData = [{ id: 1, name: 'Emily' }, { id: 2, name: 'Lucy' }] Speakers = React.createClass render: -> rows = _.chunk(speakersData, 4) div className: 'speakers', @_buildRows() _buildRows: -> rows.map (row) -> row.map (speaker) -> div className: 'speaker', speaker.name
  • 37. Proof of Concept (try #2) speakersData = [{ id: 1, name: 'Emily' }, { id: 2, name: 'Lucy' }] Speakers = React.createClass render: -> rows = _.chunk(speakersData, 4) div className: 'speakers', @_buildRows() _buildRows: -> rows.map(@_buildSpeakers) _buildSpeakers: (row) -> row.map (speaker) -> div className: 'speaker', speaker.name
  • 38.
  • 39. Proof of Concept (try #3) speakersData = [{ id: 1, name: 'Emily' }, { id: 2, name: 'Lucy' }] Speakers = React.createClass render: -> rows = _.chunk(speakersData, 4) div className: 'speakers', rows.map (row) -> Row(row: row) Row = React.createClass render: -> div null, # render must return a React.DOM element or null @props.row.map (speaker) -> Speaker(speaker: speaker) Speaker = React.createClass render: -> div className: 'speaker', @props.speaker.name
  • 40. Nice work! Take a breath.
  • 43. Speakers = React.createClass componentWillMount: -> @_fetchSpeakers() render: -> # ...
  • 44. Speakers = React.createClass componentWillMount: -> @_fetchSpeakers() render: -> # ... _fetchSpeakers: -> SomeAjaxHelper .get('speakers.json') .then(@_onSuccess) _onSuccess: (data) -> # triggers a re-render @setState(speakers: data)
  • 45. Speakers = React.createClass componentWillMount: -> @_fetchSpeakers() render: -> # what do you think happens here? rows = _.chunk(@state.speakers, 4) div className: 'speakers', rows.map (row) -> Row(row: row) _fetchSpeakers: -> # ... _onSuccess: (data) -> @setState(speakers: data)
  • 46. React waits for no code. Speed is the name of the game. React calls the render method unless specifically told not to. When there is no initial state nor inital speakers property, @state (and thus, speakers) is undefined.
  • 47. We could do... Speakers = React.createClass componentWillMount: -> @_fetchSpeakers() render: -> if @state and @state.speakers and @state.speakers.length > 0 rows = _.chunk(@state.speakers, 4) div className: 'speakers', rows.map (row) -> Row(row: row) else null # ...
  • 48. or we could do... Speakers = React.createClass componentWillMount: -> @_fetchSpeakers() render: -> if @state?.speakers?.length > 0 rows = _.chunk(@state.speakers, 4) div className: 'speakers', rows.map (row) -> Row(row: row) else null # ...
  • 49. The Right Way™ Speakers = React.createClass # With this we now have an initial bit of # data for our speakers state. getInitialState: -> speakers: [] componentWillMount: -> @_fetchSpeakers() render: -> if @state.speakers.length > 0 rows = _.chunk(@state.speakers, 4) div className: 'speakers', rows.map (row) -> Row(row: row) else null # or a Loader
  • 50. Building the Child Components
  • 51. Row Component Row = React.createClass render: -> div null, @props.row.map (item) => Speaker(speaker: item)
  • 52. Speaker Component Speaker = React.createClass render: -> div className: 'speaker', img className: 'speaker__image', src: @props.speaker.image div className: 'speaker__infoBox', div className: 'speaker__info', h3 className: 'speaker__name', @props.speaker.name span null, @props.speaker.work
  • 53. Adding info toggling functionality
  • 54. What do we need? Keep track of currently selected item Ability to insert the info at the end of a group Click event that toggles the info for an item
  • 55. Speakers = React.createClass getInitialState: -> speakers: [] selectedId: -1 # or null, if you prefer render: -> # ... rows.map (row) -> Row( row: row selectedId: @state.selectedId updateSelectedId: @_updateSelectedId ) _updateSelectedId: (selectedId) -> @setState(selectedId: selectedId)
  • 56. Row = React.createClass render: -> div null, @_buildRow() _buildRow: -> selectedItems = @_filterSelected() rendered = @props.row.map (item) => Speaker( isSelected: item.id is @props.selectedId speaker: item updateSelectedId: @props.updateSelectedId ) if selectedItems.length > 0 rendered.push(Info(speaker: selectedItems[0])) rendered _filterSelected: -> @props.row.filter (item) => item.id is @props.selectedId
  • 57. Speaker = React.createClass render: -> div className: 'speaker', onClick: @_handleToggleClick, img className: 'speaker__image', src: @props.speaker.image div className: 'speaker__infoBox', div className: 'speaker__info', h3 className: 'speaker__name', @props.speaker.name span null, @props.speaker.work # Determines selectedId value and # triggers the callback function # passed down from Speakers _handleToggleClick: -> # b/c i don't have room for a proper if/else selectedId = @props.speaker.id selectedId = -1 if @props.isSelected # reset! @props.updateSelectedId(selectedId)
  • 58. Info = React.createClass render: -> div className: 'speakerInfo', h3 null, @props.speaker.name p null, div null, @props.speaker.work div null, @props.speaker.twitter p null, @props.speaker.bio
  • 59. Rendering to the DOM // index.js var React = require('react'); var Speakers = require('./Speakers.react'); var div = document.createElement('div'); document.body.insertBefore(div, document.body.firstChild); React.render(Speakers(), div); // | | // component container
  • 60. Ship It and Pray...
  • 61. We won't go in to this, but it now is easy to add additional functionality, such as Search. Speakers = React.createClass # ... render: -> div null, Search() @_renderRows() and control the data via this main component.
  • 63. Why
  • 64. Truth
  • 65. Maintaining state in web applications. How...?
  • 66. In web applications, what has been the source of data truth since day one? The server.
  • 67.
  • 68. Mutating the DOM never made sense to me. The solution?
  • 69.
  • 70. Isn't that expensive on browsers? Nope.
  • 73. Re-rendering subset (good) Image credit: Christopher Chedeau
  • 74. Re-rendering subset (good) Image credit: Christopher Chedeau
  • 76. The previous image occurs when one component does not control all of the data for an application, or at least for a set of subcomponents.
  • 77. It's very tempting to want to manage state inside the component that the state affects.
  • 78. Remember this? Speaker = React.createClass render: -> # ... Row(updateSelectedId: @_updateSelectedId) _updateSelectedId: (selectedId) -> # ... Row = React.createClass render: -> # ... Speaker(updateSelectedId: @_updateSelectedId) Speaker = React.createClass render: -> # ... div className: 'speaker', onClick: @_handleClick # ... _handleClick: -> # ... @props.updateSelectedId(selectedId)
  • 79. Utilizing Events Speaker = React.createClass componentDidMount: -> SpeakerEmitter.addSelectionChangeListener(@_updateSelectedId) componentWillUnmount: -> SpeakerEmitter.removeSelectionChangeListener(@_updateSelectedId) render: -> Row() _updateSelectedId: (selectedId) -> # ... Row = React.createClass render: -> Speaker() Speaker = React.createClass render: -> div className: 'speaker', onClick: @_handleClick _handleClick: -> SpeakerEmitter.emitSelectionChange(selectedId)
  • 83. Client Side & Server-side You can compile React on the server and use the same templates for server-side rendering as you do for client-side.
  • 85. They're Open Source Committed
  • 86. TL;DR If your current JS framework/lib/stack makes you feel like give React a shot and see if if makes you feel like