Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

A Journey with React

764 views

Published on

FITC events. For digital creators.
Save 10% off ANY FITC event with discount code 'slideshare'
See our upcoming events at www.fitc.ca

A Journey with React
with Tasveer Singh

OVERVIEW
React has been receiving a lot of buzz lately but does it live up to it? Taz was curious about this exact question and decided to embark on a journey to find out more. Since then he has fallen in love with React, its simple paradigm, and what it has enabled him to do. From modelling large front-end applications with Flux and WebPack code splitting to search engine optimized isomorphic rendering, he really has explored React from one end to the other and will share his experience and insights with you along with tips and tricks along the way.

OBJECTIVE

To provide the audience with enough information to understand how React is different and to explore further.

TARGET AUDIENCE

Intermediate to Advanced JavaScript developers.

ASSUMED AUDIENCE KNOWLEDGE

Basic knowledge of client side JavaScript frameworks, JavaScript modules, ES6, asset management, SEO, and isomorphic JavaScript.

FIVE THINGS AUDIENCE MEMBERS WILL LEARN

What is React
How React is different
Pros and Cons of a Flux architecture
Pros and Cons of WebPack
Pros and Cons of Isomorphic JavaScript

Published in: Internet
  • Be the first to comment

  • Be the first to like this

A Journey with React

  1. 1. A J O U R N E Y W I T H R E A C T TA S V E E R S I N G H @ t a z s i n g h
  2. 2. 3 A P P S
  3. 3. – M I K E H O U R A H I N E “You can learn trigonometry, physics, C++, and DirectX to make a video game. Or you can make a video game and learn DirectX, C++, physics, and trigonometry.”
  4. 4. 0 100 Number of times you’ve built a similar app 1 2 3 4 5 6 7 ... Quality Mistakes Made
  5. 5. A P P # 1 - R E A C T A S A T E M P L AT I N G E N G I N E • Server side application framework • Nashorn JavaScript engine for Java 8 • Vert.x 2.3 - Polyglot Event-Driven Messaging • Innovative Router • React to describe HTML
  6. 6. A P P # 2 - F L U X
  7. 7. M C C C C V V V V M
  8. 8. M C C C C V V V V M
  9. 9. A P P # 2 - F L U X • My first iteration relied on my experience from MVC • Business logic resides in Models/Stores • Fat models, skinny controllers • Models/Stores make AJAX calls • Actions were very light weight notifications to the Stores
  10. 10. function signInUser(username, password) { Dispatcher.dispatch({ type: ActionTypes.USER_SIGN_IN , username: username , password: password }); }
  11. 11. class UserStore extends EventEmitter { currentUser = null; dispatchToken = Dispatcher.register((action) => { switch(action.type) { case ActionTypes.USER_SIGN_IN: fetchUser(action.username, action.password).then( (response) => { this.currentUser = response.user; this.emit(“change”); }); } }); }
  12. 12. function getState() { return { currentUser: UserStore.currentUser } } class SignInComponent extends React.Component { state = getState(); handleStateChange() { this.setState(getState()); } componentDidMount() { UserStore.on(“change”, this.handleStateChange); } componentWillUnmount() { UserStore.removeListener(“change”, this.handleStateChange); } handleAuth(event) { signInUser(prompt(“What’s your username?”), prompt(“What’s your password?”)); } render() { if(!this.state.currentUser) return <a onClick={this.handleAuth}>Click here to sign in</a>; else return <p>You’re signed in as {this.state.currentUser.name}</p>; } }
  13. 13. A P P # 2 - F L U X - F I R S T I T E R AT I O N • Facebook’s Dispatcher does not allow you to dispatch from a dispatch • Difficult to compose application flow • How do you handle errors? • Relies on the Global State of ActionTypes • Views worked great!
  14. 14. N E X T I T E R AT I O N T RY C O M P O S I N G A C T I O N S
  15. 15. class SignInUser extends BaseAction { constructor(username, password, alreadySignedInUser) { this.username = username; this.password = password; this.alreadySignedInUser = alreadySignedInUser; if(!this.alreadySignedInUser) this.authUser(); } authUser() { fetchUser(this.username, this.password).then( (newUser) => { new SignInSuccess(newUser); } , (errors) => { new SignInFailure(errors); } ); }
  16. 16. class SignInUser extends BaseAction { constructor(username, password, alreadySignedInUser) { this.username = username; this.password = password; this.alreadySignedInUser = alreadySignedInUser; if(!this.alreadySignedInUser) this.authUser(); } authUser() { fetchUser(this.username, this.password).then( (newUser) => { new SignInSuccess(newUser); } , (errors) => { new SignInFailure(errors); } ); }
  17. 17. class SignInSuccess extends BaseAction { constructor(newUser) { this.newUser = newUser; this.dispatch(); } } class SignInFailure extends BaseAction { constructor(errors) { this.errors = errors; this.dispatch(); new FlashMessage(“Could not sign in”); } }
  18. 18. class UserStore extends EventEmitter { currentUser = null; dispatchToken = Dispatcher.register((action) => { switch(action.constructor) { case SignInSuccess: this.currentUser = action.newUser; this.emit(“change”); } }); }
  19. 19. A P P # 2 - F L U X - 2 N D I T E R AT I O N • Eliminates the “dispatching from a dispatch” problem • Stores are synchronous • Very easy to compose the flow of your application by composing actions • Eliminated Global State of ActionTypes • Extremely scalable solution • Easy to test • In a later iteration, dropped in WebPack
  20. 20. A P P # 3 - B R O C H U R E W E B S I T E
  21. 21. A P P # 3 - B R O C H U R E W E B S I T E • SEO is paramount • AJAX is bad for SEO • Performant on Desktop and Mobile • Server Side Rendered • Incremental Loading • Introduce server side developers to client side technologies • ES6/ES2015 via Babel • React + Flux + WebPack
  22. 22. A P P # 3 - B R O C H U R E W E B S I T E • Server side React + Server side Flux • WebPack manages front end assets, inlining, and chunking • Incremental loading by chunking • Reduce number of web requests by inlining • Koa.js serves the application and handles routing
  23. 23. 0 100 Number of times you’ve built a similar app 1 2 3 4 5 6 7 ... Quality Mistakes Made
  24. 24. 0 100 Number of times you’ve built a similar app 1 2 3 4 5 6 7 ... Quality Mistakes Made
  25. 25. 0 100 Number of times you’ve built a similar app 1 2 3 4 5 6 7 ... Quality Mistakes Made
  26. 26. G R I F F I N . J S
  27. 27. G R I F F I N . J S • Includes everything I’ve learnt and more • Facebook’s Dispatcher • React Views • Griffin Actions - Same as previous examples • Redux Stores w/ Griffin Connector to Views
  28. 28. class UserStore extends EventEmitter { currentUser = null; dispatchToken = Dispatcher.register((payload) => { switch(payload.constructor) { case SignInSuccess: this.currentUser = payload.newUser; this.emit(“change”); } }); }
  29. 29. class UserStore extends GriffinStore { reducer(state = null, action) => { switch(action.constructor) { case SignInSuccess: return payload.newUser; default: return state; } }); }
  30. 30. function getState() { return { currentUser: UserStore.currentUser } } class SignInComponent extends React.Component { state = getState(); handleStateChange() { this.setState(getState()); } componentDidMount() { UserStore.on(“change”, this.handleStateChange); } componentWillUnmount() { UserStore.removeListener(“change”, this.handleStateChange); } handleAuth(event) { signInUser(prompt(“What’s your username?”), prompt(“What’s your password?”)); } render() { if(!this.state.currentUser) return <a onClick={this.handleAuth}>Click here to sign in</a>; else return <p>You’re signed in as {this.state.currentUser.name}</p>; } }
  31. 31. @connect({ currentUser: UserStore }) class SignInComponent extends React.Component { handleAuth(event) { signInUser(prompt(“What’s your username?”), prompt(“What’s your password?”)); } render() { if(!this.props.currentUser) return <a onClick={this.handleAuth}>Click here to sign in</a>; else return <p>You’re signed in as {this.props.currentUser.name}</p>; } }
  32. 32. R E A C T D E P E N D E N C Y I N J E C T I O N • Using props to pass in external data is similar to Angular’s dependency injection • Only use state to manage internal component state • <SignInComponent currentUser={{name: “Mock User!”}} /> • <SignInComponent currentUser={null} />
  33. 33. R E A C T R O U T E R
  34. 34. R E A C T R O U T E R • Amazing routing solution - Inspired heavily by Ember’s router • Ember has an excellent router • Uses JSX or JSON to describe routes and nested routes • React Component will be loaded by a Route • Version 1.0 has lazy loading of routes and components • Better Server Side Rendering
  35. 35. React.render(( <Router> <Route path="/" component={App}> <Route path="about" component={About} /> <Route path="inbox" component={Inbox}> <Route path="messages/:id" component={Message} /> </Route> </Route> </Router> ), document.body)
  36. 36. . ├── AppComponent.js => / ├── AboutComponent.js => /about ├── InboxComponent.js => /inbox └── MessageComponent.js => /inbox/messages/:id
  37. 37. . ├── AppComponent.js => / ├── AboutComponent.js => /about ├── InboxComponent.js => /inbox └── inbox    └── MessageComponent.js => /inbox/messages/:id
  38. 38. . ├── index.js => / ├── about │   └── index.js => /about └── inbox    ├── index.js => /inbox    └── messages    └── @id    └── index.js => /inbox/messages/:id
  39. 39. . ├── index.js => / ├── about │   └── index.js => /about └── inbox    ├── DeleteMessage.js    ├── GetMessages.js    ├── MessageStore.js    ├── index.js => /inbox    └── messages    └── @id    └── index.js => /inbox/messages/:id
  40. 40. React.render(( <Router> <Route path="/" component={App}> <Route path="about" component={About} /> <Route path="inbox" component={Inbox}> <Route path="messages/:id" component={Message} /> </Route> </Route> </Router> ), document.body)
  41. 41. G R I F F I N F I L E S Y S T E M B A S E D R O U T I N G • Easy to initialize your app • import myApp from “griffin!.”;
 myApp({ /* any griffin options here */}); • Easy to mount other apps • import anotherApp from “griffin!/path/to/app”;
 anotherApp({ /* griffin options */});
  42. 42. U N I V E R S A L A P P S W I T H W E B PA C K • Everything goes through WebPack • Based on James Long’s excellent “Backend Apps with WebPack” posts • On the server, it ignores CSS, images, etc. • WebPack enables lazy-loading of application chunks • Incrementally load Griffin routes • Include common modules with initial payload
  43. 43. G R I F F I N . J S S TAT U S • Almost ready for release • Planning to release in the next few months • I’m currently rewriting the WebPack incremental file-system based routing • Last core item remaining before release
  44. 44. 0 100 Number of times you’ve built a similar app 1 2 3 4 5 6 7 ... Quality Mistakes Made
  45. 45. T H A N K Y O U @ t a z s i n g h

×