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.

React HOCs, Context and Observables

517 views

Published on

Presentation discusses the best practices when writing higher order components (HOCs), and presents examples how to write them according to React recommendations.

Topics include: maximizing HOC factories composability, using ES7 decorators, wrapping context DI in HOCs, handling async state changes using RxJS Observanels and separation of concerns between presentation and business logic components. Examples (@GitHub projects - referenced in the presentation) are given using react, redux, react-router-redux, redux-observable, recompose, and reselect.

Published in: Software
  • Be the first to comment

React HOCs, Context and Observables

  1. 1. Using Context, Higher-Order Components and Observables with React Slide 1Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Sofia May 15, 2017 Context, HOCs & Observables with React Trayan Iliev IPT – Intellectual Products & Technologies e-mail: tiliev@iproduct.org web: http://www.iproduct.org
  2. 2. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 2Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License About Us: IPT - Intellectual Products & Technologies Since 2003 we provide trainings and share knowledge in JS/ TypeScript/ Node/ Express/ Socket.IO/ NoSQL/ Angular/ React / Java SE/ EE/ Web/ REST SOA: Node.js + Express/ hapi + React.js + Redux + GraphQL Angular + TypeScript + Redux (ngrx) Java EE6/7, Spring, JSF, Portals/Portlets: Liferay, GateIn Reactive IoT with Reactor / RxJava / RxJS SOA & Distributed Hypermedia APIs (REST) Domain Driven Design & Reactive Microservices
  3. 3. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 3Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Where is The Code? React.js demo code is available @GitHub: https://github.com/iproduct/demos-and-presentations Demos: react-router-redux-demo – React + Redux + Router + Thunk (async actions) integration react-hocs-observables – React + Redux + Router + RxJS Observables (async action stream transforms) + Reselect + Recompose + Material-UI
  4. 4. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 4Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Contemporary Web Applications Provide better User Experience (UX) by: more interactive loading and reacting faster in response (or even anticipation) of user's moves able to work offline supporting multiple devices and screen resolutions (responsive design) are following design metaphors consistently (e.g. Google Material Design - MD) looking more like desktop application than static web page
  5. 5. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 5Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License MVC Comes in Different Flavors MVC MVVM MVP Sources:https://en.wikipedia.org/wiki/Model_View_ViewModel#/media/File:MVVMPattern.png, https://en.wikipedia.org/wiki/Model %E2%80%93view%E2%80%93presenter#/media/File:Model_View_Presenter_GUI_Design_Pattern.png License: CC BY-SA 3.0, Authors:Ugaya40, Daniel.Cardenas
  6. 6. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 6Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Single Page Applications (SPA) Source: http://stackoverflow.com/questions/12863663/complex-nesting-of-partials-and-templates Author: PhillipKregg
  7. 7. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 7Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License SPA with Multiple Router Outlets
  8. 8. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 8Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Why SPA? Page does not flicker – seamless (or even animated) transitions Less data transferred – responses are cached Only raw data, not markup Features can be loaded on demand (lazy) or in background Most page processing happens on the client offloading the server: REST data services + snapshops for crawlers (SEO) Code reuse – REST endopints are general purpose Supporting multiple platforms (Web, iOS, Android) → React Native
  9. 9. Using Context, Higher-Order Components and Observables with React Slide 9Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Sofia May 15, 2017 Developing Sinagle Page Apps (SPA) in 3 steps 1) Setting up a build system – npm, webpack, gulp are common choices, babel, typescript, JSX, CSS preprocessors (SASS, SCSS, LESS, PostCSS), servers ... 2) Designing front-end architecture components – views & layouts + view models (presentation data models) + presentation logic (event handling, messaging) + routing paths (essential for SPA) Better to use component model to boost productivity and maintainability. 3) End-to-end application design – front-end: wireframes → views, data entities & data streams → service API and models design, sitemap → router config
  10. 10. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 10Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Components Resuability - Two Approaches Inheritance - we create new component Types (or Classes) by extending exiting ones – Class Hierachy: Composition: Object composition Functional composition
  11. 11. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 11Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Object Composition Hierachy
  12. 12. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 12Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Functional Composition Functional programming (FP) - the mathematical notion of function composition Composing functions f and g, g(f(x)) means f’s out → g’s input In FP, the inputs and outputs are values without life cycles Simpler to understand compared to object compositions If input-output types match, functions can always compose! More sophisticated forms of composition can be implemented using higher-order functions: functions can be passed as inputs and received as outputs to/from other functions Functions are just immutable values – no special treatment!
  13. 13. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 13Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Higher-Order Components Higher-order component (HOC) is a function that takes a component and returns a new component: const EnhancedComponent = higherOrderComponent( WrappedComponent ); Example: const VisibleTodoList = connect(mapStateToProps, mapDispatchToProps) (TodoList);
  14. 14. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 14Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Use HOCs For Cross-Cutting Concerns class BlogPost extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); this.state = { blogPost: DataSource.getBlogPost(props.id) }; } componentDidMount(){DataSource.addChangeListener(this.handleChange);} componentWillUnmount() { DataSource.removeChangeListener(this.handleChange);} handleChange() { this.setState({blogPost: DataSource.getBlogPost(this.props.id)}); } render() { return <TextBlock text={this.state.blogPost} />; } }
  15. 15. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 15Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Use HOCs For Cross-Cutting Concerns (2) function withSubscription(WrappedComponent, selectData) { return class extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); this.state = {data: selectData(DataSource, props) }; } componentDidMount() { DataSource.addChangeListener(this.handleChange); } componentWillUnmount({ DataSource.removeChangeListener(this.handleChange);} handleChange() { this.setState({data: selectData(DataSource, this.props)});} render() { return <WrappedComponent data={this.state.data} {...this.props}/>;} }; } Anonimous class. Name should be added using dispalyName static property
  16. 16. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 16Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Usage: const CommentListWithSubscription = withSubscription( CommentList, (DataSource) => DataSource.getComments() ); const BlogPostWithSubscription = withSubscription( BlogPost, (DataSource, props) => DataSource.getBlogPost(props.id) });
  17. 17. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 17Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Using HOCs – Things To Remember: Don't Mutate the Original Component. Use Composition. Convention: Pass Unrelated Props Through to the Wrapped Component Convention: Maximizing Composability const ConnectedComment = connect(commentSelector, commentActions)(Comment); // compose(f, g, h) is the same as (...args) => f(g(h(...args))) const enhance = compose(withRouter, connect(commentSelector, commentActions) ); enhance(Comment); Convention: Wrap the Display Name for Easy Debugging The order matters!
  18. 18. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 18Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License How to Boost Performance with React Use the production build Avoiding reconciling the DOM – React provides a component lifecycle function, shouldComponentUpdate, which is triggered before the re-rendering process starts (virtual DOM comparison and possible eventual DOM reconciliation), giving the developer the ability to short circuit this process. Default: shouldComponentUpdate: function(nextProps, nextState) { return true; } React invokes shouldComponentUpdate often -should be fast Use immutability for comparisons to be efficient
  19. 19. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 19Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Performance with shouldComponentUpdate class MyStatelessComp extends React.Component { static propTypes = { value: PropTypes.string.isRequired }; shouldComponentUpdate: function(nextProps, nextState) { return this.props.value !== nextProps.value; }, render: function() { return <div>{this.props.value}</div>; } });
  20. 20. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 20Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Boosting Performance: PureRenderMixin Before – using mixins(Mixins Considered Harmful by Dan Abramov): var PureRenderMixin = require('react-addons-pure-render-mixin'); React.createClass({ mixins: [PureRenderMixin], render: function() { return <div className={this.props.className}>foo</div>; } }); Now you should prefer: class MyComponent extends React.PureComponent { … }
  21. 21. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 21Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Using HOCs – Caveats: Don't Use HOCs Inside the render Method: render() { const EnhancedComponent = enhance(MyComponent); return <EnhancedComponent />; } Static Methods Must Be Copied Over Maximizing Composability Refs Aren't Passed Through Don't
  22. 22. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 22Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Refs to Components Refs (references) – allow to find the DOM markup rendered by a component, and invoke methods on component instances returned from render() Example uses: absolute positioning, using React components in larger non-React applications, transition existing code to React. var myComponentInstanceRef = ReactDOM.render(<MyComp />, myContainer); myComponentInstanceRef.doSomething(); ReactDOM.findDOMNode(componentInstance) – this function will return the DOM node belonging to the outermost HTML element returned by render.
  23. 23. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 23Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License The ref Callback Attribute render: function() { return ( <TextInput ref={ function(input) { if (input != null) { input.focus(); } }} /> ); }, OR better using ES6 => : render: function() { return <TextInput ref={(c) => this._input = c} />; }, componentDidMount: function() { this._input.focus(); }, Will be called twice – on mount with ref, and on unmount with null. That is why we check if ref not null.
  24. 24. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 24Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Using React Component Context React props allow to track data-flow easy between componets React Context is alternative if you want to pass data through the component tree without having to pass the props down manually at every level. Inversion of Control (IoC) principle and Dependency Injection (DI) pattern React's "context" feature lets you do this – Example how to inject testService and router in TestsList component: TestsList.contextTypes = { testService: React.PropTypes.object, router: React.PropTypes.object };
  25. 25. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 25Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Passing Refs from Wrapped Comp to HOC function Field({ inputRef, ...rest }) { return <input ref={inputRef} {...rest} />; } // Wrap Field in a higher-order component const EnhancedField = enhance(Field); // Inside a class component's render method... <EnhancedField inputRef={(inputEl) => { // This callback gets passed through as a regular prop this.inputEl = inputEl }} /> // Now you can call imperative methods this.inputEl.focus();
  26. 26. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 26Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Providing Services with React Context class IPTKnowledgeTester extends React.Component { constructor(props) { super(props); this.testServiceSingleton = new TestService(TEST_SERVICE_URL); this.localeServiceSingleton = new LocaleService(DEFAULT_LOCALE, this.onLocaleChange); } getChildContext() { return { testService: this.testServiceSingleton, localeService: this.localeServiceSingleton }; } … } IPTKnowledgeTester.childContextTypes = { testService: React.PropTypes.object, localeService: React.PropTypes.object };
  27. 27. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 27Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License React Context Usage Example handleAddTest() { const path = { pathname: '/test', query: { controls: true, edit: true } }; this.context.router.push(path); } componentDidMount() { this.context.testService.getTests().then((tests) => { this.setState({ tests: tests }); }); }
  28. 28. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 28Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Referencing Context in Lifecycle Methods void componentWillReceiveProps( object nextProps, object nextContext ) boolean shouldComponentUpdate( object nextProps, object nextState, object nextContext ) void componentWillUpdate( object nextProps, object nextState, object nextContext ) void componentDidUpdate( object prevProps, object prevState, object prevContext )
  29. 29. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 29Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Using Context with Functional Components const Button = ({children}, context) => <button style={{background: context.color}}> {children} </button>; Button.contextTypes = {color: React.PropTypes.string};
  30. 30. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 30Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License React Router v4 Configuration <Route path="/" component={Base} /> <Route path="/home" component={Home} /> <Route path="/intro" render={() => <div>How to start using this app</div>} /> <Route path="/repos" component={Repos} /> <Route path="/topics" component={Topics} /> <Route path="/about" component={About} /> <Route path="/show-location" component={ShowTheLocation} /> const Repos = (props) => { return ( <div> <h2>Repos</h2> <Route path="/repos/:userName/:repoName" component={Repo} /> </div> ); }; Hierarchical navigation, no need to use props.children
  31. 31. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 31Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Site Navigation using Router v4 <ul className="main-menu"> <li><Link to="/home">Home</Link></li> <li><Link to="/intro">Intro</Link></li> <li><Link to="/repos">Repos</Link></li> <li><Link to="/topics">Topics</Link></li> <li><Link to="/show-location">Show the Location</Link></li> <li><Link to="/about">About</Link></li> <form className="navbar-form navbar-right" role="search" onSubmit={this.handleSerch}> <input type="text" placeholder="userName" /> / {' '} <input type="text" placeholder="repo" /> {' '} <button type="submit" className="btn btn-default">Go</button> </form> </ul>
  32. 32. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 32Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Programmatic Navigation using Router v4 ReactDOM.render( <Router > <App /> </Router>, document.getElementById('root') ); handleSerch = (event) => { event.preventDefault(); const userName = event.target.elements[0].value; const repo = event.target.elements[1].value; const path = `/repos/${userName}/${repo}`; console.log(path); console.log(this.context); // this.context.router.history.push(path); this.props.history.push(path); }
  33. 33. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 33Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Using @withRouter Decorator (HOC) - Router v4 import React from 'react'; import PropTypes from 'prop-types'; import { withRouter } from 'react-router-dom'; @withRouter export default class ShowTheLocation extends React.Component { render() { const { match, location, history } = this.props; return ( <div> <div>You are now at {location.pathname}</div> <div>The match is: {JSON.stringify(match)}</div> <div>The history contains: {JSON.stringify(history)}</div> </div> ) } }
  34. 34. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 34Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Flux Design Pattern Source: Flux in GitHub, https://github.com/facebook/flux, License: BSD 3-clause "New" License
  35. 35. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 35Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Redux Design Pattern Source: @ngrx/store in GitHub, https://gist.github.com/btroncone/a6e4347326749f938510 Linear flow:
  36. 36. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 36Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Redux Streamlined state management for React.js applications, inspired by Redux State is a single immutable data structure Actions describe state changes Pure functions called reducers take the previous state and the next action to compute the new state State is kept within single Store, and accessed through sub- state selectors, or as Observable of state changes Components are by default perfomance optimized using the shouldComponentUpdate() → performant change detection
  37. 37. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 37Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Redux Recommended (Basic) Project Structure actions – action creator factory functions (design pattern Command) assets – static assets (css images, fonts, etc.) folder components – simple (dumb) react components – pure render container – Redux Store aware (smart) component wrappers reducers – the only way to advance state: function(OldStoreState, Action) => NewStoreState // = Rx scan() index.js – bootstraps app providing access to Store for all containers (smart components) using React context
  38. 38. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 38Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Bootstrapping Redux App – index.js import React from 'react'; import ReactDOM from 'react-dom'; import { Provider } from 'react-redux'; import { createStore } from 'redux'; import rootReducer from './reducers'; import { FilteredTodoApp } from './containers/filtered-todo-app'; const store = createStore( rootReducer, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() ); const render = (Component) => { ReactDOM.render( <Provider store={store}> <FilteredTodoApp /> </Provider>, document.getElementById('root') ); }; Top level container component Redux store provider
  39. 39. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 39Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Redux Action Creators – /actions/index.js let nextTodoId = 0; export const addTodo = (text) => ({ type: 'ADD_TODO', id: nextTodoId++, text }); export const setVisibilityFilter = (filter) => ({ type: 'SET_VISIBILITY_FILTER', filter }); export const changeStatus = (id, status) => ({ type: 'CHANGE_STATUS', id, status }); ... Action Payload Action Type
  40. 40. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 40Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Redux Reducers – /reducers/todo.js const todoReducer = (state = {}, action) => { switch (action.type) { case 'ADD_TODO': return { id: action.id, text: action.text, status: 'active' }; case 'CHANGE_STATUS': if (state.id !== action.id) { return state; } return Object.assign({}, state, { status: action.status }); default: return state; } };
  41. 41. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 41Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Redux Reducers – /reducers/todos.js const todosReducer = (state = [], action) => { switch (action.type) { case 'ADD_TODO': return [ ...state, todoReducer(undefined, action) ]; case 'CHANGE_STATUS': return state.map(todo => todoReducer(todo, action) ); case 'DELETE_TODOS': return state.filter(todo => todo.status !== action.status ); default: return state; } };
  42. 42. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 42Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Redux Root Reducer – /reducers/index.js import { combineReducers } from 'redux'; import todos from './todos'; import visibilityFilter from './visibilityFilter'; const rootReducer = combineReducers({ todos, visibilityFilter }); export default rootReducer;
  43. 43. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 43Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Redux Containers – /conatiners/visible-todo-list.js const getVisibleTodos = (todos, filter) => todos.filter( todo => filter === 'all' ? true: todo.status === filter); const mapStateToProps = (state) => ({ todos: getVisibleTodos(state.todos, state.visibilityFilter) }); const mapDispatchToProps = (dispatch) => ({ onCompleted: (id) => { dispatch(changeStatus(id, 'completed')); }, onCanceled: (id) => { dispatch(changeStatus(id, 'canceled')); } }); const VisibleTodoList = connect(mapStateToProps, mapDispatchToProps ) (TodoList); export default VisibleTodoList;
  44. 44. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 44Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Redux App using ES7 @connect Decorator const getVisibleTodos = (todos, filter) => todos.filter( todo => filter === 'all' ? true: todo.status === filter); const mapStateToProps = (state) => ({ todos: getVisibleTodos(state.todos, state.visibilityFilter) }); const mapDispatchToProps = (dispatch) => ({ onCompleted: (id) => { dispatch(changeStatus(id, 'completed')); }, onCanceled: (id) => { dispatch(changeStatus(id, 'canceled')); } }); @connect(mapStateToProps, mapDispatchToProps) export default class TodoList extends React.Component { constructor(props) { ...
  45. 45. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 45Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Using Redux Router Redux and Redux Thunk (1) Idea: history + store (redux) → react-router-redux → enhanced history → react- router import { compose, createStore, combineReducers, applyMiddleware } from 'redux'; import { Provider } from 'react-redux'; import createHistory from 'history/createBrowserHistory'; import { ConnectedRouter, routerReducer, routerMiddleware, push } from 'react-router-redux'; // React Router to Redux integration import thunk from 'redux-thunk'; // Allows using thunks = async actions import reducers from './reducers'; // your reducers here const history = createHistory(); // use browser History API // middleware for intercepting & dispatching navigation & async actions const middleware = [routerMiddleware(history), thunk]; // Enable Redux Devtools const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
  46. 46. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 46Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Using Redux Router Redux and Redux Thunk (2) const store = createStore( CombineReducers({ ...reducers, router: routerReducer // Add the reducer to store on `router` key }), /* preloadedState, */ ComposeEnhancers( applyMiddleware(...middleware) )); store.dispatch(push('/repos/react/redux'));//dispatch navigation action ReactDOM.render( <Provider store={store}>//ConnectedRouter use store from the Provider <ConnectedRouter history={history}> <App /> </ConnectedRouter> </Provider>, document.getElementById('root') )
  47. 47. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 47Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Redux Thunk Async Actions - /actions/counter.js export function increment(x) { return { type: INCREMENT, amount: x } } export function incrementAsync(x) { return dispatch => //Can invoke sync or async actions with `dispatch` setTimeout(() => { dispatch(increment(x)); }, 2000); } export function incrementIfOdd(x) { return (dispatch, getState) => { const { counter } = getState(); if (counter.number % 2 === 0) return; dispatch(increment(x)); //Can invoke actions conditionally }; }
  48. 48. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 48Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Advanced Redux using Middleware Libraries Normalizr – normalizing and denormalizing data in state, helps to transform nested JSON response structures into a relational DB-like plain entities, referenced by Id in the Redux store. redux-thunk – in addition to plain actions, Action Creators can now return Thunks – callback functions of dispatch and getState arguments, allowing to handle async operations like data fetch from REST endpoint and Promise-like composition. redux-promise/ redux-promise-middleware – thunk alternatives redux-observable – really powerfull reactive transforms of async action events as RxJS Observables, called Epics: (action$:Observable<Action>, store:Store) => Observable<Action>
  49. 49. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 49Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Functional Reactive Programming Functional Reactive Programming (FRP) [Wikipedia]: a programming paradigm for reactive programming (asynchronous dataflow programming) using the building blocks of functional programming (e.g. map, reduce, filter). FRP has been used for programming graphical user interfaces (GUIs), robotics, and music, aiming to simplify these problems by explicitly modeling time. Ex. (RxJS): const Observable = require('rxjs').Observable; Observable.from(['Reactive', 'Extensions', 'JavaScript']) .take(2).map(s => `${s}: on ${new Date()}`) .subscribe(s => console.log(s)); Result: Reactive: on Sat Apr 29 2017 20:00:39 GMT+0300 Extensions: on Sat Apr 29 2017 20:00:39 GMT+0300 Good intro tutorial in RP using RxJS by Andre Staltz see: https://gist.github.com/staltz/868e7e9bc2a7b8c1f754 JS Fiddle of the demo: http://jsfiddle.net/staltz/8jFJH/48/
  50. 50. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 50Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Definitions of Reactive Programming Microsoft® opens source polyglot project ReactiveX (Reactive Extensions) [http://reactivex.io]: Rx = Observables + LINQ + Schedulers :) Supported Languages – Java: RxJava, JavaScript: RxJS, C#: Rx.NET, C#(Unity): UniRx, Scala: RxScala, Clojure: RxClojure, C++: RxCpp, Ruby: Rx.rb, Python: RxPY, Groovy: RxGroovy, JRuby: RxJRuby, Kotlin: RxKotlin, Swift: RxSwift ReactiveX for platforms and frameworks: RxNetty, RxAndroid, RxCocoa Reactive Streams Specification [http://www.reactive-streams.org/]
  51. 51. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 51Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License RxJS – JS ReactiveX (Reactive Extensions) [http://reactivex.io, https://github.com/ReactiveX] ReactiveX is a polyglot library for composing asynchronous event streams (observable sequences). It extends the observer pattern by declarative composition of functional transformations on events streams (e.g. map-filter- reduce, etc.) Abstracs away low-level concerns like concurrency, synchronization, and non-blocking I/O. Follows the next - error - completed event flow Allows natural implementation of Redux design pattern Alternative (together with promises) for solving “callback hell” problem
  52. 52. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 52Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Resources: RxMarbles and RxJS Coans RxMarbles: http://rxmarbles.com/ RxJS Coans: https://github.com/Reactive-Extensions/RxJSKoans
  53. 53. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 53Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Demo Time :) React.js demo code is available @GitHub: https://github.com/iproduct/demos-and-presentations Demos: react-router-redux-demo – React + Redux + Router + Thunk (async actions) integration react-hocs-observables – React + Redux + Router + RxJS Observables (async action stream transforms) + Reselect + Recompose + Material-UI
  54. 54. Using Context, Higher-Order Components and Observables with React Sofia May 15, 2017 Slide 54Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License Thank’s for Your Attention! Trayan Iliev CEO of IPT – Intellectual Products & Technologies http://iproduct.org/ http://robolearn.org/ https://github.com/iproduct https://twitter.com/trayaniliev https://www.facebook.com/IPT.EACAD https://plus.google.com/+IproductOrg

×