54
Using Context, Higher-Order Components and Observables with React Slide 1 Sources: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: [email protected] web: http://www.iproduct.org

React HOCs, Context and Observables

Embed Size (px)

Citation preview

Page 1: React HOCs, Context and Observables

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

SofiaMay 15, 2017

Context, HOCs & Observables with React

Trayan Iliev

IPT – Intellectual Products & Technologiese-mail: [email protected]

web: http://www.iproduct.org

Page 2: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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

Page 3: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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) integrationreact-hocs-observables – React + Redux + Router + RxJS Observables (async action stream transforms) + Reselect + Recompose + Material-UI

Page 4: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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

Page 5: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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.pngLicense: CC BY-SA 3.0, Authors:Ugaya40, Daniel.Cardenas

Page 6: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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-templatesAuthor: PhillipKregg

Page 7: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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

Page 8: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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

Page 9: React HOCs, Context and Observables

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

SofiaMay 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

Page 10: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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

Page 11: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 15, 2017

Slide 11Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License

Object Composition Hierachy

Page 12: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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!

Page 13: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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);

Page 14: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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 Concernsclass 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} />; }}

Page 15: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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

Page 16: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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)

});

Page 17: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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 Composabilityconst 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!

Page 18: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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

Page 19: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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>; }});

Page 20: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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 { … }

Page 21: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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

Page 22: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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.

Page 23: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 15, 2017

Slide 23Sources:ReactJS [https://github.com/facebook/react/ ] Licensed under the Creative Commons Attribution 4.0 International Public License

The ref Callback Attributerender: 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.

Page 24: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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 };

Page 25: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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 componentconst 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 methodsthis.inputEl.focus();

Page 26: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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 Contextclass 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};

Page 27: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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 });

});

}

Page 28: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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)

Page 29: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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};

Page 30: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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

Page 31: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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>

Page 32: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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); }

Page 33: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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';

@withRouterexport 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> ) }}

Page 34: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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

Page 35: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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:

Page 36: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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

Page 37: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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

Page 38: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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 componentRedux store provider

Page 39: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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 PayloadAction Type

Page 40: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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; }};

Page 41: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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; }};

Page 42: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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;

Page 43: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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;

Page 44: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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) { ...

Page 45: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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 integrationimport thunk from 'redux-thunk'; // Allows using thunks = async actionsimport reducers from './reducers'; // your reducers hereconst history = createHistory(); // use browser History API// middleware for intercepting & dispatching navigation & async actionsconst middleware = [routerMiddleware(history), thunk];// Enable Redux Devtoolsconst composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

Page 46: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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'))

Page 47: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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 };}

Page 48: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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>

Page 49: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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/868e7e9bc2a7b8c1f754JS Fiddle of the demo: http://jsfiddle.net/staltz/8jFJH/48/

Page 50: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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: RxSwiftReactiveX for platforms and frameworks: RxNetty, RxAndroid, RxCocoa

Reactive Streams Specification [http://www.reactive-streams.org/]

Page 51: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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 flowAllows natural implementation of Redux design patternAlternative (together with promises) for solving “callback hell” problem

Page 52: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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

Page 53: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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) integrationreact-hocs-observables – React + Redux + Router + RxJS Observables (async action stream transforms) + Reselect + Recompose + Material-UI

Page 54: React HOCs, Context and Observables

Using Context, Higher-Order Components and Observables with React

SofiaMay 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