Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ES6, React and Redux

ES6, React and Redux

a pretty long introduction to ecmascript 6, react and redux

Michele Carrì

January 29, 2016
Tweet

Other Decks in Technology

Transcript

  1. ES6, REACT AND REDUX ‣ ES6 ‣ React ‣ Redux

    ‣ Demo ‣ Case History TOPICS
  2. ECMASCRIPT 6 / ECMASCRIPT 2015 ‣ Variable types ‣ Arrow

    functions ‣ Modules ‣ Classes ‣ A lot more… WHAT’S NEW? Complete Feature List: http://es6-features.org/
  3. ECMASCRIPT 6 / ECMASCRIPT 2015 IMMUTABLE VARIABLES 1 const MY_CONSTANT

    = 1; 2 MY_CONSTANT = 2 // Error https://www.smashingmagazine.com/2015/10/es6-whats-new-next-version-javascript/
  4. ECMASCRIPT 6 / ECMASCRIPT 2015 BLOCK-SCOPED VARIABLES 1 if(true) {

    2 let x = 1; 3 } 4 console.log(x); // undefined 5 6 7 for(let i = 0, l = list.length; i < l; i++) { 8 // do something with list[i] 9 } 10 11 console.log(i); // undefined https://www.smashingmagazine.com/2015/10/es6-whats-new-next-version-javascript/
  5. ECMASCRIPT 6 / ECMASCRIPT 2015 ARROW FUNCTIONS https://www.smashingmagazine.com/2015/10/es6-whats-new-next-version-javascript/ 1 let

    books = [ 2 {title: 'X', price: 10}, 3 {title: 'Y', price: 15} 4 ]; 5 6 let titles = books.map( item => item.title ); 7 8 // ES5 equivalent: 9 var titles = books.map(function(item) { 10 return item.title; 11 });
  6. ECMASCRIPT 6 / ECMASCRIPT 2015 ARROW FUNCTIONS https://www.smashingmagazine.com/2015/10/es6-whats-new-next-version-javascript/ 1 let

    book = { 2 title: 'X', 3 sellers: ['A', 'B'], 4 printSellers() { 5 this.sellers.forEach((seller) => { 6 console.log(seller + ' sells ' + this.title); 7 }); 8 } 9 }
  7. ECMASCRIPT 6 / ECMASCRIPT 2015 ARROW FUNCTIONS https://www.smashingmagazine.com/2015/10/es6-whats-new-next-version-javascript/ 1 //

    ES5 equivalent: 2 var book = { 3 title: 'X', 4 sellers: ['A', 'B'], 5 printSellers: function() { 6 var that = this; 7 this.sellers.forEach(function(seller) { 8 console.log(seller + ' sells ' + that.title) 9 }) 10 } 11 }
  8. ECMASCRIPT 6 / ECMASCRIPT 2015 MODULES 1 // lib/math.js 2

    3 export function sum(x, y) { 4 return x + y; 5 } 6 export var pi = 3.141593; 1 // app.js 2 3 import { sum, pi } from "lib/math"; 4 console.log('PiGreco = ' + sum(pi, pi)); https://www.smashingmagazine.com/2015/10/es6-whats-new-next-version-javascript/
  9. ECMASCRIPT 6 / ECMASCRIPT 2015 MODULES 1 // lib/my-fn.js 2

    3 export default function() { 4 console.log('echo echo'); 5 } 1 // app.js 2 3 import doSomething from 'lib/my-fn'; 4 doSomething(); https://www.smashingmagazine.com/2015/10/es6-whats-new-next-version-javascript/
  10. ECMASCRIPT 6 / ECMASCRIPT 2015 1 class Vehicle { 2

    constructor(name) { 3 this.name = name; 4 this.kind = 'vehicle'; 5 } 6 getName() { 7 return this.name; 8 } 9 } 10 11 // Create an instance 12 let myVehicle = new Vehicle('rocky'); CLASSES https://www.smashingmagazine.com/2015/10/es6-whats-new-next-version-javascript/
  11. ECMASCRIPT 6 / ECMASCRIPT 2015 CLASSES 1 class Car extends

    Vehicle { 2 constructor(name) { 3 super(name); 4 this.kind = ‘car'; 5 } 6 } 7 8 let myCar = new Car('bumpy'); 9 10 myCar.getName(); // 'bumpy' 11 myCar instanceof Car; // true 12 myCar instanceof Vehicle; //true https://www.smashingmagazine.com/2015/10/es6-whats-new-next-version-javascript/
  12. ECMASCRIPT 6 / ECMASCRIPT 2015 SPREAD OPERATOR https://www.smashingmagazine.com/2015/10/es6-whats-new-next-version-javascript/ 1 let

    values = [1, 2, 4]; 2 let some = [...values, 8]; 3 // [1, 2, 4, 8] 4 5 let more = [...values, 8, ...values]; 6 // [1, 2, 4, 8, 1, 2, 4] 7 8 // ES5 equivalent: 9 let values = [1, 2, 4]; 10 // Iterate, push, sweat, repeat... 11 // Iterate, push, sweat, repeat...
  13. ECMASCRIPT 6 / ECMASCRIPT 2015 SPREAD OPERATOR https://www.smashingmagazine.com/2015/10/es6-whats-new-next-version-javascript/ 1 let

    values = [1, 2, 4]; 2 3 doSomething(...values); 4 5 function doSomething(x, y, z) { 6 // x = 1, y = 2, z = 4 7 } 8 9 // ES5 equivalent: 10 doSomething.apply(null, values);
  14. ECMASCRIPT 6 / ECMASCRIPT 2015 SO, WHAT EXACTLY CAN I

    USE? Browsers Support inconsistent between browsers. Microsoft Edge is one best in ES6 support. :-) Node Partial support. Some features are available only on versions > 5 and need to be explicitly enabled with a runtime flag.
  15. REACT JUST FOR THE UI React is all about modular,

    composable components. Not necessarily web components. It makes no assumptions about the rest of your technology stack.
  16. REACT VIRTUAL DOM Keep track of state in DOM is

    hard! It’ll be so easier to re-render the whole DOM on every change. Unfortunately the DOM API is not so fast.
  17. REACT ONE WAY DATA FLOW The only way to pass

    data thought different components is from top to bottom. No two way bindings.
  18. REACT JSX return <div>Hello {this.props.name}</div>; React components are written in

    JSX, a JavaScript extension syntax allowing easy quoting of HTML and using HTML tag syntax to render components.
  19. REACT LET’S CREATE A COMPONENT! 1 // hello_message.js 2 3

    import React from 'react'; 4 import ReactDOM from 'react-dom'; 5 6 class HelloMessage extends React.Component { 7 render() { 8 return <div>Hello {this.props.name}</div>; 9 } 10 } 11 12 const mountNode = document.getElementById('example'); 13 ReactDOM.render(<HelloMessage name="John" />, mountNode);
  20. REACT PROPS ‣ Props contain anything you need to render

    your component ‣ You can use string, functions, objects or arrays as a prop ‣ Props should be considered immutable ‣ Mutating props is bad
  21. REACT PROPTYPES PropTypes defines type and which props are required.

    1 //example 1 2 MyComponent.propTypes = { 3 size: React.PropTypes.number, 4 position: React.PropTypes.string.isRequired 5 } 6 7 //example 2 8 MyComponent.propTypes ={ 9 position: React.PropTypes.oneOf(['fixed', 'absolute']) 10 }
  22. REACT PROPTYPES 1 //example 3 2 3 MyComponent.propTypes = {

    4 email: (props, propName, componentName) => { 5 if (!/emailRegex/.test(props[email])) { 6 return new Error('Give me a real email!'); 7 } 8 }, 9 user: React.PropTypes.shape({ 10 name: React.PropTypes.string.isRequired, 11 age: React.PropTypes.number 12 }).isRequired 13 }
  23. REACT NESTED COMPONENTS 1 // profile.js 2 3 import React

    from 'react'; 4 5 class Profile extends React.Component{ 6 render(){ 7 return ( 8 <div> 9 <img src={this.props.avatar} /> 10 <span>{this.props.name}</span> 11 </div> 12 ); 13 } 14 }
  24. REACT NESTED COMPONENTS 1 // app.js 2 3 import React

    from 'react'; 4 import ReactDOM from 'react-dom'; 5 import Profile from './profile'; 6 7 class App extends React.Component{ 8 render(){ 9 return ( 10 <div> 11 <h1>Hello World!</h1> 12 <Profile avatar="http://test.png" name="Nik" /> 13 </div> 14 ); 15 } 16 } 17 18 const exampleNode = document.getElementById('example'); 19 ReactDOM.render(<App />, exampleNode);
  25. REACT IF/ELSE (1) 1 // profile.js 2 3 import React

    from 'react'; 4 5 class Profile extends React.Component{ 6 render(){ 7 8 let AdminIcon; 9 10 if (this.props.isAdmin) { 11 AdminIcon = (<span>green</span>); 12 } 13
  26. REACT IF/ELSE (2) 14 return ( 15 <div> 16 <img

    src={this.props.avatar} /> 17 <span>{this.props.name}</span> 18 {AdminIcon} 19 </div> 20 ); 21 } 22 }
  27. REACT LOOPS 1 // list.js 2 3 import React from

    'react'; 4 5 class List extends React.Component{ 6 render(){ 7 return ( 8 <ul> 9 {this.props.friends.map((friend) => { 10 return <li>{friend.name}</li>; 11 })} 12 </ul> 13 ); 14 } 15 }
  28. REACT INTERACTIONS 1 // profile.js 2 3 import React from

    'react'; 4 5 class Profile extends React.Component{ 6 7 notify(){ 8 console.log('NOCIIIIII!') 9 } 10 11 render(){ 12 return ( 13 <div onClick={(e) => this.notify(e)}> 14 <img src={this.props.avatar} /> 15 <span>{this.props.name}</span> 16 </div> 17 ); 18 } 19 }
  29. REACT STATE AND SET STATE ‣ state is a property

    that can keep the component state ‣ setState is a function that change the current state ‣ when setState is called the component automatically call render again
  30. REACT LET’S CREATE A STATEFUL COMPONENT! 1 // like_button.js 2

    3 import React from 'react'; 4 import ReactDOM from 'react-dom'; 5 6 class LikeButton extends React.Component { 7 constructor(){ 8 super(); 9 this.state = {liked: false}; 10 } 11 handleClick() { 12 this.setState({liked: !this.state.liked}); 13 }
  31. REACT LET’S CREATE A STATEFUL COMPONENT! 14 render() { 15

    var text = this.state.liked ? 'like' : 'haven\'t liked'; 16 return ( 17 <p onClick={this.handleClick}> 18 You {text} this. Click to toggle. 19 </p> 20 ); 21 } 22 } 23 24 const mountNode = document.getElementById('example'); 25 ReactDOM.render(<LikeButton />, mountNode);
  32. REACT COMPONENT STATE ‣ Most of your components should simply

    take some data from props and render it. ‣ State should contain data that a component's event handlers may change to trigger a UI update. ‣ Try to keep as many of your components as possible stateless.
  33. REACT NOT ONLY ON THE DOM… The react-dom/server package allows

    you to render your components on the server.
  34. REACT SERVER SIDE RENDERING 1 // hello_message.js 2 3 import

    React from 'react'; 4 import ReactDOMServer from 'react-dom/server'; 5 6 class HelloMessage extends React.Component { 7 render() { 8 return <div>Hello {this.props.name}</div>; 9 } 10 } 11 12 ReactDOMServer.renderToString(<HelloMessage />);
  35. REACT NOT ONLY ON THE DOM… You can even build

    almost native mobile applications!
  36. REACT REACT NATIVE ‣ Same programming paradigm of React ‣

    Javascript is executed by iOS / Android ‣ RN “bridge” invokes the native rendering APIs in Objective-C / Java ‣ RN works separately from the main UI thread ‣ You can still write native code and a bridge for js
  37. REACT REACT NATIVE 1 // iOS 2 3 var React

    = require('react-native'); 4 var { TabBarIOS, NavigatorIOS } = React; 5 6 var App = React.createClass({ 7 render: function() { 8 return ( 9 <TabBarIOS> 10 <TabBarIOS.Item title="React Native" selected={true}> 11 <NavigatorIOS initialRoute={{ title: 'React Native' }} /> 12 </TabBarIOS.Item> 13 </TabBarIOS> 14 ); 15 }, 16 });
  38. REACT TESTING ‣ Jest - https://facebook.github.io/jest ‣ Mocha ‣ Jasmine

    ‣ React Test Utilities ‣ Enzyme - https://github.com/airbnb/enzyme
  39. REACT SUMMARY ‣ We can build components ‣ We can

    build an applications with several different components ‣ We can keep our application state inside the state of our components
  40. REACT SUMMARY Be careful because maintaining your application state within

    the state of your components isn’t a great idea…
  41. REDUX WHAAAAT? Redux allows you to manage the state with

    a minimal API but completely predictable behaviour.
  42. REDUX THE APPLICATION STATE 1 { 2 todos: [ 3

    { 4 text: 'Learn React', 5 completed: true 6 }, 7 { 8 text: 'Learn Redux', 9 completed: false 10 } 11 ] 12 }
  43. REDUX ACTIONS 1 const action = { 2 type: 'ADD_TODO',

    3 text: 'Send a message to GPad!', 4 }
  44. REDUX ACTION CREATORS 1 function addTodo(text) { 2 return {

    3 type: 'ADD_TODO', 4 text: text 5 } 6 }
  45. REDUX REDUCERS 1 const todos = (state = [], action)

    => { 2 switch (action.type) { 3 case 'ADD_TODO': 4 return [ 5 ...state, 6 { 7 text: action.text, 8 completed: false 9 } 10 ] 11 default: 12 return state 13 } 14 }
  46. REDUX INSPIRED BY ELM 1 type Action = Increment |

    Decrement 2 3 update action model = 4 case action of 5 Increment -> model + 1 6 Decrement -> model - 1 http://elm-lang.org
  47. REDUX STORE 1 import { createStore } from 'redux'; 2

    import todoReducer from '../reducers'; 3 4 let store = createStore(todoReducer); 5 6 store.subscribe( 7 () => console.log(store.getState()) 8 ) 9 10 store.dispatch(addTodo('Send a message to GPad!')); 11 store.dispatch(addTodo('Send a message to mk!'));
  48. REDUX ASYNC ACTION CREATORS 1 function fetch() 2 return dispatch

    => { 3 dispatch(loadingAction()); 4 doSomeAjax(...) 5 .then(function(response) { 6 dispatch(successAction, successAction(response.data)); 7 } 8 } 9 }
  49. REDUX REACT + REDUX 1 import React from 'react'; 2

    import ReactDOM from 'react-dom'; 3 import { createStore } from 'redux'; 4 5 import { Provider } from 'react-redux'; 6 7 import todoApp from './reducers'; 8 import App from './components/App'; 9 10 let store = createStore(todoApp); 11 12 let exampleNode = document.getElementById('example'); 13 14 ReactDOM.render( 15 <Provider store={store}> 16 <App /> 17 </Provider>, 18 exampleNode 19 );
  50. REDUX REACT + REDUX 1 import React from 'react'; 2

    import { connect } from 'react-redux'; 3 import { addTodo } from '../actions.js'; 4 5 class App extends React.Component { 6 render(){ 7 const { dispatch } = this.props; 8 return( 9 <button onClick={ dispatch(addTodo('Call GPad!')) }> 10 Add Todo 11 </button> 12 ); 13 } 14 } 15 16 export default connect((state) => state)(App)
  51. REDUX SMART AND DUMP COMPONENTS Technically all components could be

    connect to the store but that’s a very bad idea!
  52. REDUX SMART AND DUMP COMPONENTS The best behavior is to

    connect only top level components and pass actions to other components using props.
  53. REDUX SMART AND DUMP COMPONENTS 1 // app.js 2 3

    import React from 'react'; 4 import Profile from './profile'; 5 import { connect } from 'react-redux'; 6 import { openModal } from '../actions'; 7 8 9 class App extends React.Component{ 10 11 clickHandler(){ 12 const { dispatch } = this.props; 13 dispatch(openModal()); 14 } 15
  54. REDUX SMART AND DUMP COMPONENTS 16 render(){ 17 return (

    18 <div> 19 <h1>Hello World!</h1> 20 <Profile avatar="http://test.png" 21 name="Nik" 22 onImageClick={() => this.clickHandler()}/> 23 </div> 24 ); 25 } 26 } 27 28 export default connect((state) => state)(App)
  55. REDUX SMART AND DUMP COMPONENTS 1 // profile.js 2 3

    import React from 'react'; 4 5 class Profile extends React.Component{ 6 render(){ 7 return ( 8 <div> 9 <img src={this.props.avatar} onClick={this.props.onImageClick}/> 10 <span>{this.props.name}</span> 11 </div> 12 ); 13 } 14 } 15 16 export default Profile;
  56. REDUX SUMMARY ‣ Reusable Components ‣ Easy to understand ‣

    Performant & Lightweight ‣ Reducers are very easy to test
  57. REACT & REDUX ARE THEY PRODUCTION READY? React - Used

    by Facebook, AirBnb and many more… Redux - Used by Firefox, Docker, coders51 and many more… :-)
  58. ?

  59. ?

  60. CASE HISTORY 1 CURRENT SCENARIO & REQUESTS ‣ Customer with

    several different applications (Rails, Wordpress, etc) ‣ Need a way to show how much time is left to the release date of a film
  61. CASE HISTORY 1 SOLUTION Javascript library that mounts a React

    component. The component fetch the data needed from an api and show the countdown.
  62. CASE HISTORY 1 PRO ‣ No code duplication across different

    apps ‣ Easily embeddable by anyone in any stack
  63. CASE HISTORY 2 CURRENT SCENARIO ‣ Medium size Rails app

    already in production ‣ Growing ecosystem with several different applications ‣ Need to share some common basic features between every application
  64. CASE HISTORY 2 REQUESTED FEATURES ‣ Toolbar ‣ Real time

    notifications ‣ Friendship Management ‣ Internationalization Management ‣ Banner Management ‣ Footer
  65. CASE HISTORY 2 SOLUTION Javascript components library with some great

    APIs to interact with the underlying applications.
  66. CASE HISTORY 2 PRO ‣ No code duplication across different

    apps ‣ Consistent way to manage real time notifications and messaging via websocket ‣ Easily embeddable in any stack
  67. CASE HISTORY 3 CURRENT SCENARIO ‣ HUGE size Rails app

    already in production ‣ Several pages with large list of articles (very similar to a Facebook timeline…) ‣ A lot of duplicated code ‣ Poor rendering performance ‣ jQuery + Handlebars
  68. CASE HISTORY 3 SOLUTION Timeline is now a react component

    and it’s rendered both server side and client side (if needed)
  69. CASE HISTORY 3 PRO ‣ No code duplication (server side

    rendering) ‣ No more DOM based code ‣ More readable and testable code ‣ Fast
  70. ?