learning react: facebook's javascript library for building user interfaces
TRANSCRIPT
I do amazing things at Media Hive in Red Bank, NJ
&
Build a bunch of open source stuff in my free time
▸ Just The View Layer▸ Component Based▸ Virtual DOM
▸ Unidirectional Data Flow▸ Server Side Rendering
▸ Low Learning Curve & Small API▸ Virtual DOM = Performance▸ SEO problem solved▸ Statefulness▸ Standalone
// JSXrender: function(){ return ( <div className=’test’>Hello</div> )}
//JSrender: function(){ return ( React.DOM.div({className: ‘test’}, ‘hello’) )}
COMPONENTSvar MyComponent = React.createClass({ render: function(){ return ( <h1>Hello World</h1> ) }});
COMPONENTSvar MyComponent = React.createClass({ render: function(){ return ( <h1>Hello World</h1> ) }});
React.render(<MyComponent/>, document.body);
COMPONENTSvar OtherComponent = React.createClass({ render: function(){ return ( <h1>Hello World</h1> ) }})
var MyComponent = React.createClass({ render: function(){ return ( <div className="container"> <OtherComponent/> </div> ) }});
React.render(<MyComponent/>, document.body);
JSX GOTCHAS<div className="myClass"></div>
<label htmlFor="myInput"></label>
render: function() { return ( <div> <FirstComponent/> <AdjacentComponent/> </div> )}
PROPSvar MyComponent = React.createClass({ render: function(){ return ( <h1>{this.props.message}</h1> ) }});
React.render(<MyComponent message="Hello World"/>, document.body);
STATEvar MyComponent = React.createClass({ getInitialState: function() { return { message: "Hello World" } }, render: function(){ return ( <h1>{this.state.message}</h1> ) }});
React.render(<MyComponent/>, document.body);
▸ componentWillMount▸ componentDidMount
▸ componentWillReceiveProps▸ shouldComponentUpdate▸ componentWillUpdate▸ componentDidUpdate▸ componentWillUnmount
KEYSvar MyComponent = React.createClass({ getInitialState: function() { return { todos: ["Listen to Tupac", "Don't eat bread", "Put up Christmas decorations"] } }, render: function(){ var items = this.state.todos.map(function(todo){ return <li>{todo}</li> }) return ( <ul> {items} </ul> ) }});
React.render(<MyComponent/>, document.body);
KEYSvar MyComponent = React.createClass({ getInitialState: function() { return { todos: ["Listen to Tupac", "Don't eat bread", "Put up Christmas decorations"] } }, render: function(){ var items = this.state.todos.map(function(todo, index){ return <li key={index}>{todo}</li> }) return ( <ul> {items} </ul> ) }});
React.render(<MyComponent/>, document.body);
REFSvar MyComponent = React.createClass({ handleSubmit: function(){ console.log(this.refs.nameInput.value) }, render: function(){ return ( <form onSubmit={this.handleSubmit}> <label htmlFor="nameInput">Enter your name:</label> <input type="text" name="nameInput" ref="nameInput"/> </form> ) }});
React.render(<MyComponent/>, document.body);
EVENTSvar MyComponent = React.createClass({ handleClick: function(){ alert('I Got Clicked!') }, render: function(){ return ( <a href="#" onClick={this.handleClick}/>Click Me</a> ) }});
React.render(<MyComponent/>, document.body);
SERVER SIDE REACT// server.js
var state = {todos: ["Get in a fistfight", "Buy chain wallet"]}var markup = React.renderToString(<MyComponent/>);
res.render('index',{ markup: markup, state: state});
SERVER SIDE REACT// index.handlebars
<html><head></head><body>{{{ markup }}}<script id="app-state" type="application/json">{{{state}}}</script></body></html>
SERVER SIDE REACT// client.js
var state = JSON.parse(document.getElementById('app-state').innerHTML);
React.render(<MyComponent state={state}/>, document.body);
FLUX ARCHITECTURE
▸ Global Pub/Sub System▸ Actions send data and action type to Dispatcher
▸ Dispatcher sends actions to Stores & enforces dependencies▸ Stores receive data, update their data and notify Views
▸ Views update & call actions
THIS SUCKSvar ChildComponent = React.createClass({ render: function(){ <a href="#" onClick={this.props.onClick}/> }})
var TopComponent = React.createClass({ handleClick: function(){ console.log('meh'); }, render: function(){ return ( <ChildComponent onClick={this.handleClick}/> ) }})
DISPATCHER// Dispatcher.js
// Creates a new dispatcher and attaches it to mcFly.dispatchervar mcFly = new McFly();
module.exports = mcFly;
ACTIONS// TodoActions.js
var TodoActions = mcFly.createActions({ addTodo: function(todo){ return { actionType: 'ADD_TODO', todo: todo } }})
module.exports = TodoActions;
STORES//TodoStore.js
var _todos = [];
function addTodo(todo){ _todos = _todos.push(todo);}
var TodoStore = mcFly.createStore({ getTodos: function(){ return _todos; }}, function(payload){ if(payload.actionType === "ADD_TODO") { addTodo(payload.todo); TodoStore.emitChange(); }})
module.exports = TodoStore;
VIEWSvar TodoList = React.createClass({ mixins: ['TodoStore.mixin'], getInitialState: function(){ return { todos: TodoStore.getTodos() } }, addTodo: function(){ TodoActions.addTodo(this.refs.todoInput.value); }, render: function(){ var todos = this.state.todos.map(function(todo,index){ return <li key={index}>{todo}</li> }) return ( <div className="todos-app"> <ul className="todos"> {todos} </ul> <input type="text" ref="todoInput"/> <input type="submit" onClick={this.addTodo} value="Add Todo"/> </div> ) }})