Skip to content

Instantly share code, notes, and snippets.

@dmsnell
Created November 2, 2015 06:01
Show Gist options
  • Save dmsnell/42b4a1583351fc93490e to your computer and use it in GitHub Desktop.
Save dmsnell/42b4a1583351fc93490e to your computer and use it in GitHub Desktop.
Presentation on React for TucsonJS, November 2015

How to React

and why you should


{
  "name": "Dennis Snell",
  "title": "Spline Reticulator",
  "company": "Automattic, Inc.",
  "presentationDate": "Thurs, Nov 5, 2015"
}

This is not a tutorial

This is not a library

React is the implementation of
[the ideas behind React]
β€” Pete Hunt

What are the ideas behind React?

  • Declarative UI
  • Lifecycles
  • Single responsibility principle

What are the ideas behind React?

Declarative UI

view = f( state )
view = f( state )
view = f( state )

UI views are a direct translation from their input parameters to the output display.

view = f( actions.reduce( handleAction ) )


Declarative UI

const Meetup = ( { title, date, description, attendees } ) => (
	<div>
		<h1>{ title }</h1>
		<h2>{ moment( date ).format( 'L' ) }</h2>
		<div className="description">{ description }</div>
		{ attendees.length ?
			<h2>Who's coming?</h2>
			<ul>
				{ attendees.map( user => (
					<li><User {...user} /></li>
				) ) }
			</ul>
		: <h2>Be the first to sign up!</h2> }
	</div>
);

No transitions means one-way data bindings.


import { togglePostLike } from 'actionHandler';

render( post ) {
	return (
		<LikeButton
			isLiked={ post.isLiked }
			onClick={ () => togglePostLike( post.ID ) }
		/>
	);
}

What are the ideas behind React?

Lifecycles

React components are objects with specific lifecycle methods that get called at the appropriate time if they exist.


Lifecycles

getInitialState()
getDefaultProps()
componentWillMount()
componentDidMount()
getInitialState()
shouldComponentUpdate()
componentWillUnmount()


componentDidMount() {
	productStore
		.fetchCategory( this.props.category )
		.then( products => products.map( prepareForDisplay ) )
		.then( products => this.setState( { products } ) );
}

render() {
	return (
		<div>
			{ this.state.products.map( product => (
				<Product {...product } />
			) }
		</div>
	);
}

Server-side, client-side, render-time are _lifecycle_ moments...

..._Isomorphic_ React apps


By using the appropriate lifecycle methods we can pre-render on the server and spit out valid HTML. Once the client JavaScript loads, React hooks up the event-handlers and starts building the Virtual DOM.

same code on the server and client


What are the ideas behind React?

Single responsibility principle

  • Reusable component libraries
  • Composable components and enhancers
  • Separation of data, mutations, and views

componentDidMount() {
	fetch( LANGUAGE_USE_JSON_URL )
		.then( response => response.json() )
		.then( data => this.setState( { data } ) );
}

render: () => (
	<table>
		<tr><th>...</th></tr>
		{ this.state.data.languages.map( this.getLanguageRow ) }
	</table>
);

Not so good!

Hard-coded API requests

Interleaving of data

Not reusable


componentDidMount() {
	surveyStore.fetchResults()
		.then( data => this.setState( { data } ) );
}

render: () => (
	<table>
		<tr><th>...</th></tr>
		{ this.state.data.languages.map( this.getLanguageRow ) }
	</table>
);

Better...

πŸ‘ API is abstracted

πŸ‘Ž Data still interleaved

πŸ‘Ž Still not reusable


render: ( headers, rows ) => (
	<table>
		<tr>
			{ headers.map( header => (
				<th>{ header }</th>
			) ) }
		</tr>
		{ rows.map( row => (
			<tr>
				{ row.map( cell => (
					<td>{ cell }</td>
				) ) }
			</tr>
		) ) }
	</table>
);

Is a table

Only a table


// Data wrapper
componentDidMount() {
	surveyStore.fetchResults()
		.then( data => this.setState( { data } ) );
}

render: () => (
	<DataTable
		headers={ ... }
		rows={ this.state.data.languages }
	/>
);

Best

πŸ‘ API is abstracted

πŸ‘ Data fetching totally separate

πŸ‘ Table is completely reusable (_testable_)


// TableUnitTest
const fixture = {
	headers: [ 'Animal', 'Voice', 'Constraint' ],
	rows: [
		[ 'Cat', 'meow', 'must land on feet' ],
		[ 'Horse', 'neigh', 'follows carrots' ],
		[ 'Octocat', '*$%!', 'reverts when bugs spotted' ]
	]
}

let table = render( <DataTable {...fixture } /> );

assert( hasThreeRows( table ) );

table.sortByVoice();
assert( isSortedByVoice( table ) );

Composability lends itself to inserting via the AST

render: () => (
	<TransitionLogger {...this.props}>
		<ComponentVisualizer>
			<LanguageUseTable />
		</ComponentVisualizer>
	</TransitionLogger>
);

Why should I react?


React has the weight of Facebook behind it.

It's supported and stable.


It's more than a library;

it's a body of constraints that impose

certain assumptions on your code


Instead of freaking out about these constraints, embrace them. Let them guide you. Constraints drive innovation and force focus. Instead of trying to remove them, use them to your advantage.

β€” 37 Signals


...the imagination is unleashed by constraints. You break out of the box by stepping into shackles.

β€” Jonah Lehrer


Rules are the fence around a playground that allow us to have fun and explore and imagine without fear and without risk.

β€” Me? I swear I heard this somewhere before...


Enumerate the benefits

  • Modular, composable, reusable components
  • Low entry to barrier for new contributors
  • Avoids the data disaster
  • Can render to non-DOM media
  • Plays well with others: jQuery, d3, etc...
  • Makes designers happy
  • Incremental application
  • Great performance

Time for a live demo!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment