on building interfaces - Everything is a component - Virtual DOM - lightweight rendering based on differences of state of the component - JSX harmony syntax React var HelloMessage = React.createClass({ render: function () { return <div> Hello {this.props.name} </div>; }; }); React.render(<HelloMessage name=”John” />, mountNode);
build a full front end application we use: React and supporting stack Node.js is a cross-platform runtime environment for applications written in JavaScript. Gulp is a fast and intuitive streaming build tool built on Node.js. Browserify lets you require('modules') in the browser by bundling up all of your dependencies. npm is the package manager for nodejs Bower is a package management system for client-side programming. Sass (Syntactically Awesome Stylesheets) is a stylesheet language.
of the UI, and break it down into a component hierarchy. Based on this diagram, the component hierarchy for the Employee Directory app looks like this: - App - HomePage - Header - SearchBar - EmployeeList - EmployeeListItem - EmployeePage - Header - EmployeeDetails Thinking in React
component with some hardcoded (static) sample data. Iteration 1: Static Version Highlights Result How to run $ cd /home/seedstars/react/1.Initial $ npm install $ ./node_modules/gulp/bin/gulp.js
hierarchy from HomePage to EmployeeListItem. In this version, we make data (the search key to be specific) flow upstream, from the SearchBar to the HomePage where it is used to find the corresponding employees. Iteration 3: Inverse Data Flow Highlights Update homepage var HomePage = React.createClass({ searchHandler:function(key) { alert('Search key: ' + key); }, <SearchBar searchHandler={this.searchHandler}/> var SearchBar = React.createClass({ getInitialState: function() { return {searchKey: ""}; }, searchHandler: function(event) { var searchKey = event.target.value; this.setState({searchKey: searchKey}); this.props.searchHandler(searchKey); }, render: function () { return ( <input type="search" value={this.state.symbol} onChange={this.searchHandler}/> ); } }); Update SearchBar
service. In this sample app, we use a mock in-memory service (defined in data.js) that uses promises so you can easily replace the implementation with Ajax calls. We keep track of the search key and the list of employees in the HomePage state. Iteration 4: Async Data and State Highlights Update homepage var HomePage = React.createClass({ getInitialState: function() { return {employees: []} }, searchHandler:function(key) { this.props.service.findByName(key).done(function(result) { this.setState({searchKey: key, employees: result}); }.bind(this)); }, render: function () { return ( <div> <Header text="Employee Directory"/> <SearchBar searchHandler={this.searchHandler}/> <EmployeeList employees={this.state.employees}/> </div> ); } }); React.render( <HomePage service={employeeService}/>, Add helper var employeeService = require('./data.jsx');
the application now has more than one view, we add support for react-router. Iteration 5: Routing A Highlights Create new page var EmployeePage = React.createClass({ getInitialState: function() { return {employee: {}}; }, componentDidMount: function() { console.log(this.props.params.employeeId); this.props.service.findById(this.props.params.employeeId).done(function(result) { this.setState({employee: result}); }.bind(this)); }, render: function () { return ( <div> <Header text="Employee Details"/> <h3>{this.state.employee.firstName} {this.state.employee.lastName}</h3> {this.state.employee.title} </div> ); } });
In this version, we use the Ratchet CSS library to provide the app with a mobile skin. Highlights $ cd /home/seedstars/react/2.Design $ npm install $ ./node_modules/gulp/bin/gulp.js bower $ ./node_modules/gulp/bin/gulp.js How to run
EmployeePage, HomePage has lost its state (search key and employee list). In this version, we fix this problem and make sure the state is preserved. Iteration 7: Maintaining State A Highlights Update homepage var HomePage = React.createClass({ render: function () { return ( <div> <Header text="Employee Directory" back="false"/> <SearchBar searchKey={this.props.searchKey} searchHandler={this.props.searchHandler}/> <div className="content"> <EmployeeList employees={this.props.employees}/> </div> </div> ); } });
React and Cordova http://coenraets.org/blog/2014/12/sample-mobile-application-with-react-and-cordova/ - Facebook React Page http://facebook.github.io/react/ - React Router - route handling https://github.com/rackt/react-router - Reflux - Flux architecture implementation https://github.com/spoike/refluxjs - gulp.js streaming build system http://gulpjs.com/ - Bower - a package manager for the web http://bower.io/ - Browserify transform for JSX (superset of JavaScript used in React library by Facebook) https://github.com/andreypopp/reactify References