full-stack development with node.js and react.js http...

35
Copyright © 2003-2017 IPT – Intellectual Products & Technologies Ltd. All rights reserved. Full-stack Development with Node.js and React.js IPT – Intellectual Products & Technologies http://www.iproduct.org/ 16/02/2017 Slide 1 SPA and Routing with React.js. Redux. Trayan Iliev IPT – Intellectual Products & Technologies e-mail: [email protected] web: http://www.iproduct.org Oracle®, Java™ and JavaScript™ are trademarks or registered trademarks of Oracle and/or its affiliates. Microsoft .NET, Visual Studio and Visual Studio Code are trademarks of Microsoft Corporation. Other names may be trademarks of their respective owners.

Upload: nguyenque

Post on 20-Mar-2018

231 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Full-stack Development with Node.js and React.js http ...iproduct.org/wp-content/uploads/2017/05/IPT_React_2017_06.pdf · Full-stack Development with Node.js and React.js IPT –

Copyright © 2003-2017 IPT – Intellectual Products & Technologies Ltd. All rights reserved.

Full-stack Development with Node.js and React.js

IPT – Intellectual Products & Technologieshttp://www.iproduct.org/

16/02/2017 Slide 1

SPA and Routing with React.js. Redux.

Trayan Iliev

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

web: http://www.iproduct.org

Oracle®, Java™ and JavaScript™ are trademarks or registered trademarks of Oracle and/or its affiliates.Microsoft .NET, Visual Studio and Visual Studio Code are trademarks of Microsoft Corporation.

Other names may be trademarks of their respective owners.

Page 2: Full-stack Development with Node.js and React.js http ...iproduct.org/wp-content/uploads/2017/05/IPT_React_2017_06.pdf · Full-stack Development with Node.js and React.js IPT –

16/02/2017 Slide 2Copyright © 2003-2017 IPT – Intellectual Products & Technologies Ltd. All rights reserved.

Full-stack Development with Node.js and React.js

IPT – Intellectual Products & Technologieshttp://www.iproduct.org/

Where is The Code?

React.js Web App code is available @GitHub:https://github.com/iproduct/course-node-express-react

Demos:14-ipt-knowledge-tester-express – with React router v215-react-router-v4 – with React router v416-react-todos-redux – basic Redux demo17-react-todos-redux-es7-decorator – demo using @connect ES7 stage 1 decorator18-react-router-redux – React + Redux + Router + Thunk (async actions) integration

Page 3: Full-stack Development with Node.js and React.js http ...iproduct.org/wp-content/uploads/2017/05/IPT_React_2017_06.pdf · Full-stack Development with Node.js and React.js IPT –

16/02/2017 Slide 3Copyright © 2003-2017 IPT – Intellectual Products & Technologies Ltd. All rights reserved.

Full-stack Development with Node.js and React.js

IPT – Intellectual Products & Technologieshttp://www.iproduct.org/

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 4: Full-stack Development with Node.js and React.js http ...iproduct.org/wp-content/uploads/2017/05/IPT_React_2017_06.pdf · Full-stack Development with Node.js and React.js IPT –

16/02/2017 Slide 4Copyright © 2003-2017 IPT – Intellectual Products & Technologies Ltd. All rights reserved.

Full-stack Development with Node.js and React.js

IPT – Intellectual Products & Technologieshttp://www.iproduct.org/

Single Page Applications (SPA)

Source: Angular 2 Tutorial: Routing https://angular.io/docs/ts/latest/tutorial/toh-pt5.htmlLicense: CC BY 4.0.

Page 5: Full-stack Development with Node.js and React.js http ...iproduct.org/wp-content/uploads/2017/05/IPT_React_2017_06.pdf · Full-stack Development with Node.js and React.js IPT –

16/02/2017 Slide 5Copyright © 2003-2017 IPT – Intellectual Products & Technologies Ltd. All rights reserved.

Full-stack Development with Node.js and React.js

IPT – Intellectual Products & Technologieshttp://www.iproduct.org/

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: Full-stack Development with Node.js and React.js http ...iproduct.org/wp-content/uploads/2017/05/IPT_React_2017_06.pdf · Full-stack Development with Node.js and React.js IPT –

16/02/2017 Slide 6Copyright © 2003-2017 IPT – Intellectual Products & Technologies Ltd. All rights reserved.

Full-stack Development with Node.js and React.js

IPT – Intellectual Products & Technologieshttp://www.iproduct.org/

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 7: Full-stack Development with Node.js and React.js http ...iproduct.org/wp-content/uploads/2017/05/IPT_React_2017_06.pdf · Full-stack Development with Node.js and React.js IPT –

Copyright © 2003-2017 IPT – Intellectual Products & Technologies Ltd. All rights reserved.

Full-stack Development with Node.js and React.js

IPT – Intellectual Products & Technologieshttp://www.iproduct.org/

16/02/2017 Slide 7

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), jasmine, karma, protractor, live 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 8: Full-stack Development with Node.js and React.js http ...iproduct.org/wp-content/uploads/2017/05/IPT_React_2017_06.pdf · Full-stack Development with Node.js and React.js IPT –

16/02/2017 Slide 8Copyright © 2003-2017 IPT – Intellectual Products & Technologies Ltd. All rights reserved.

Full-stack Development with Node.js and React.js

IPT – Intellectual Products & Technologieshttp://www.iproduct.org/

Hierarchical Routing

Source: http://stackoverflow.com/questions/12863663/complex-nesting-of-partials-and-templatesAuthor: PhillipKregg

Page 9: Full-stack Development with Node.js and React.js http ...iproduct.org/wp-content/uploads/2017/05/IPT_React_2017_06.pdf · Full-stack Development with Node.js and React.js IPT –

16/02/2017 Slide 9Copyright © 2003-2017 IPT – Intellectual Products & Technologies Ltd. All rights reserved.

Full-stack Development with Node.js and React.js

IPT – Intellectual Products & Technologieshttp://www.iproduct.org/

SPA with Multiple Router Outlets

Page 10: Full-stack Development with Node.js and React.js http ...iproduct.org/wp-content/uploads/2017/05/IPT_React_2017_06.pdf · Full-stack Development with Node.js and React.js IPT –

16/02/2017 Slide 10Copyright © 2003-2017 IPT – Intellectual Products & Technologies Ltd. All rights reserved.

Full-stack Development with Node.js and React.js

IPT – Intellectual Products & Technologieshttp://www.iproduct.org/

React Router v2 Configuration

ReactDOM.render(( <Router history={appHistory}> <Route path="/" component={IPTKnowledgeTester}> <IndexRoute component={Home}/> <Route path="/tests" component={TestList} /> <Route path="/test(/:testId)" component={Test} /> <Route path="/users" component={UserList} /> <Route path="/user(/:userId)" component={User} /> <Route path="/repos" component={Repos}> <Route path="/repos/:userName/:repoName" component={Repo}/> </Route> <Route path="/about" component={About}/> <Route path="*" component={NoMatch}/> </Route> </Router>), document.getElementById('root'));

Page 11: Full-stack Development with Node.js and React.js http ...iproduct.org/wp-content/uploads/2017/05/IPT_React_2017_06.pdf · Full-stack Development with Node.js and React.js IPT –

16/02/2017 Slide 11Copyright © 2003-2017 IPT – Intellectual Products & Technologies Ltd. All rights reserved.

Full-stack Development with Node.js and React.js

IPT – Intellectual Products & Technologieshttp://www.iproduct.org/

Custom Link Component - NavLink

'use strict';

import React from 'react';import { Link } from 'react-router';

const NavLink = (props) => { return <Link {...props} activeClassName="active"/>}export default NavLink;

Page 12: Full-stack Development with Node.js and React.js http ...iproduct.org/wp-content/uploads/2017/05/IPT_React_2017_06.pdf · Full-stack Development with Node.js and React.js IPT –

16/02/2017 Slide 12Copyright © 2003-2017 IPT – Intellectual Products & Technologies Ltd. All rights reserved.

Full-stack Development with Node.js and React.js

IPT – Intellectual Products & Technologieshttp://www.iproduct.org/

Site Navigation using NavLink

<ul className="nav navbar-nav"> <li><NavLink to="/" onlyActiveOnIndex={true}>Home</NavLink></li> <li><NavLink to={{ pathname: '/tests', query: { controls: true } }}> Tests</NavLink></li> <li className="dropdown"> <NavLink to="/users" className="dropdown-toggle" data- toggle="dropdown">Users <span className="caret"></span></NavLink> <ul className="dropdown-menu"> <li> <NavLink to={{ pathname: '/users', query: { controls: true } }}> Manage Users</NavLink> </li><li> <NavLink to={{ pathname: '/user', query: { controls: true, edit: true } }}>Add New User</NavLink> </li><li> <NavLink to="/repos/reactjs/react-router">React Router</NavLink> </li> ...

Page 13: Full-stack Development with Node.js and React.js http ...iproduct.org/wp-content/uploads/2017/05/IPT_React_2017_06.pdf · Full-stack Development with Node.js and React.js IPT –

16/02/2017 Slide 13Copyright © 2003-2017 IPT – Intellectual Products & Technologies Ltd. All rights reserved.

Full-stack Development with Node.js and React.js

IPT – Intellectual Products & Technologieshttp://www.iproduct.org/

Programmatic Navigation with Router v2

<form className="navbar-form navbar-left" onSubmit={handleSearch}> <input type="text" placeholder="userName" className="form-control"/>/ <input type="text" placeholder="repo" className="form-control" /> <button type="submit" className="btn btn-default">Go</button></form>

const Navigation = ({children}, context) => { function handleSearch(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); // navigate programmatically context.router.push(path); // OR browserHistory.push(path); }

Page 14: Full-stack Development with Node.js and React.js http ...iproduct.org/wp-content/uploads/2017/05/IPT_React_2017_06.pdf · Full-stack Development with Node.js and React.js IPT –

16/02/2017 Slide 14Copyright © 2003-2017 IPT – Intellectual Products & Technologies Ltd. All rights reserved.

Full-stack Development with Node.js and React.js

IPT – Intellectual Products & Technologieshttp://www.iproduct.org/

Hierarchical Navigation using Path Parameters

const Repos = (props) => { return ( <div> <h2>Repos</h2> {props.children} </div> );};

const Repo = (props) => { return ( <div> <h3>{props.params.userName}: {props.params.repoName}</h3> </div> );}

Hierarchical navigation

Parsed path parameters

Page 15: Full-stack Development with Node.js and React.js http ...iproduct.org/wp-content/uploads/2017/05/IPT_React_2017_06.pdf · Full-stack Development with Node.js and React.js IPT –

16/02/2017 Slide 15Copyright © 2003-2017 IPT – Intellectual Products & Technologies Ltd. All rights reserved.

Full-stack Development with Node.js and React.js

IPT – Intellectual Products & Technologieshttp://www.iproduct.org/

Navigation using Query Parameters

import { useRouterHistory} from 'react-router';import createBrowserHistory from 'history/lib/createBrowserHistory';import { useQueries } from 'history';

const appHistory = useQueries(useRouterHistory(createBrowserHistory))();

class User extends React.Component { constructor(props, context) { super(props, context); let state = {}; // Initialize state state.isControls = this.props.isControls || (props.location && props.location.query && props.location.query.controls === 'true'); state.isEdit = this.props.isEdit || (props.location && props.location.query && props.location.query.edit === 'true');

Source: @ngrx/store in GitHub, https://github.com/ngrx/store,License: MIT

Page 16: Full-stack Development with Node.js and React.js http ...iproduct.org/wp-content/uploads/2017/05/IPT_React_2017_06.pdf · Full-stack Development with Node.js and React.js IPT –

16/02/2017 Slide 16Copyright © 2003-2017 IPT – Intellectual Products & Technologies Ltd. All rights reserved.

Full-stack Development with Node.js and React.js

IPT – Intellectual Products & Technologieshttp://www.iproduct.org/

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 17: Full-stack Development with Node.js and React.js http ...iproduct.org/wp-content/uploads/2017/05/IPT_React_2017_06.pdf · Full-stack Development with Node.js and React.js IPT –

16/02/2017 Slide 17Copyright © 2003-2017 IPT – Intellectual Products & Technologies Ltd. All rights reserved.

Full-stack Development with Node.js and React.js

IPT – Intellectual Products & Technologieshttp://www.iproduct.org/

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 18: Full-stack Development with Node.js and React.js http ...iproduct.org/wp-content/uploads/2017/05/IPT_React_2017_06.pdf · Full-stack Development with Node.js and React.js IPT –

16/02/2017 Slide 18Copyright © 2003-2017 IPT – Intellectual Products & Technologies Ltd. All rights reserved.

Full-stack Development with Node.js and React.js

IPT – Intellectual Products & Technologieshttp://www.iproduct.org/

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 19: Full-stack Development with Node.js and React.js http ...iproduct.org/wp-content/uploads/2017/05/IPT_React_2017_06.pdf · Full-stack Development with Node.js and React.js IPT –

16/02/2017 Slide 19Copyright © 2003-2017 IPT – Intellectual Products & Technologies Ltd. All rights reserved.

Full-stack Development with Node.js and React.js

IPT – Intellectual Products & Technologieshttp://www.iproduct.org/

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 20: Full-stack Development with Node.js and React.js http ...iproduct.org/wp-content/uploads/2017/05/IPT_React_2017_06.pdf · Full-stack Development with Node.js and React.js IPT –

16/02/2017 Slide 20Copyright © 2003-2017 IPT – Intellectual Products & Technologies Ltd. All rights reserved.

Full-stack Development with Node.js and React.js

IPT – Intellectual Products & Technologieshttp://www.iproduct.org/

Flux Design Pattern

Source: Flux in GitHub, https://github.com/facebook/flux, License: BSD 3-clause "New" License

Page 21: Full-stack Development with Node.js and React.js http ...iproduct.org/wp-content/uploads/2017/05/IPT_React_2017_06.pdf · Full-stack Development with Node.js and React.js IPT –

16/02/2017 Slide 21Copyright © 2003-2017 IPT – Intellectual Products & Technologies Ltd. All rights reserved.

Full-stack Development with Node.js and React.js

IPT – Intellectual Products & Technologieshttp://www.iproduct.org/

Redux Design Pattern

Source: @ngrx/store in GitHub, https://gist.github.com/btroncone/a6e4347326749f938510

Linear flow:

Page 22: Full-stack Development with Node.js and React.js http ...iproduct.org/wp-content/uploads/2017/05/IPT_React_2017_06.pdf · Full-stack Development with Node.js and React.js IPT –

16/02/2017 Slide 22Copyright © 2003-2017 IPT – Intellectual Products & Technologies Ltd. All rights reserved.

Full-stack Development with Node.js and React.js

IPT – Intellectual Products & Technologieshttp://www.iproduct.org/

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

Source: @ngrx/store in GitHub, https://github.com/ngrx/store,License: MIT

Page 23: Full-stack Development with Node.js and React.js http ...iproduct.org/wp-content/uploads/2017/05/IPT_React_2017_06.pdf · Full-stack Development with Node.js and React.js IPT –

16/02/2017 Slide 23Copyright © 2003-2017 IPT – Intellectual Products & Technologies Ltd. All rights reserved.

Full-stack Development with Node.js and React.js

IPT – Intellectual Products & Technologieshttp://www.iproduct.org/

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

Source: @ngrx/store in GitHub, https://github.com/ngrx/store,License: MIT

Page 24: Full-stack Development with Node.js and React.js http ...iproduct.org/wp-content/uploads/2017/05/IPT_React_2017_06.pdf · Full-stack Development with Node.js and React.js IPT –

16/02/2017 Slide 24Copyright © 2003-2017 IPT – Intellectual Products & Technologies Ltd. All rights reserved.

Full-stack Development with Node.js and React.js

IPT – Intellectual Products & Technologieshttp://www.iproduct.org/

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 25: Full-stack Development with Node.js and React.js http ...iproduct.org/wp-content/uploads/2017/05/IPT_React_2017_06.pdf · Full-stack Development with Node.js and React.js IPT –

16/02/2017 Slide 25Copyright © 2003-2017 IPT – Intellectual Products & Technologies Ltd. All rights reserved.

Full-stack Development with Node.js and React.js

IPT – Intellectual Products & Technologieshttp://www.iproduct.org/

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 26: Full-stack Development with Node.js and React.js http ...iproduct.org/wp-content/uploads/2017/05/IPT_React_2017_06.pdf · Full-stack Development with Node.js and React.js IPT –

16/02/2017 Slide 26Copyright © 2003-2017 IPT – Intellectual Products & Technologies Ltd. All rights reserved.

Full-stack Development with Node.js and React.js

IPT – Intellectual Products & Technologieshttp://www.iproduct.org/

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 27: Full-stack Development with Node.js and React.js http ...iproduct.org/wp-content/uploads/2017/05/IPT_React_2017_06.pdf · Full-stack Development with Node.js and React.js IPT –

16/02/2017 Slide 27Copyright © 2003-2017 IPT – Intellectual Products & Technologies Ltd. All rights reserved.

Full-stack Development with Node.js and React.js

IPT – Intellectual Products & Technologieshttp://www.iproduct.org/

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 28: Full-stack Development with Node.js and React.js http ...iproduct.org/wp-content/uploads/2017/05/IPT_React_2017_06.pdf · Full-stack Development with Node.js and React.js IPT –

16/02/2017 Slide 28Copyright © 2003-2017 IPT – Intellectual Products & Technologies Ltd. All rights reserved.

Full-stack Development with Node.js and React.js

IPT – Intellectual Products & Technologieshttp://www.iproduct.org/

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 29: Full-stack Development with Node.js and React.js http ...iproduct.org/wp-content/uploads/2017/05/IPT_React_2017_06.pdf · Full-stack Development with Node.js and React.js IPT –

16/02/2017 Slide 29Copyright © 2003-2017 IPT – Intellectual Products & Technologies Ltd. All rights reserved.

Full-stack Development with Node.js and React.js

IPT – Intellectual Products & Technologieshttp://www.iproduct.org/

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 30: Full-stack Development with Node.js and React.js http ...iproduct.org/wp-content/uploads/2017/05/IPT_React_2017_06.pdf · Full-stack Development with Node.js and React.js IPT –

16/02/2017 Slide 30Copyright © 2003-2017 IPT – Intellectual Products & Technologies Ltd. All rights reserved.

Full-stack Development with Node.js and React.js

IPT – Intellectual Products & Technologieshttp://www.iproduct.org/

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 31: Full-stack Development with Node.js and React.js http ...iproduct.org/wp-content/uploads/2017/05/IPT_React_2017_06.pdf · Full-stack Development with Node.js and React.js IPT –

16/02/2017 Slide 31Copyright © 2003-2017 IPT – Intellectual Products & Technologies Ltd. All rights reserved.

Full-stack Development with Node.js and React.js

IPT – Intellectual Products & Technologieshttp://www.iproduct.org/

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 32: Full-stack Development with Node.js and React.js http ...iproduct.org/wp-content/uploads/2017/05/IPT_React_2017_06.pdf · Full-stack Development with Node.js and React.js IPT –

16/02/2017 Slide 32Copyright © 2003-2017 IPT – Intellectual Products & Technologies Ltd. All rights reserved.

Full-stack Development with Node.js and React.js

IPT – Intellectual Products & Technologieshttp://www.iproduct.org/

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 33: Full-stack Development with Node.js and React.js http ...iproduct.org/wp-content/uploads/2017/05/IPT_React_2017_06.pdf · Full-stack Development with Node.js and React.js IPT –

16/02/2017 Slide 33Copyright © 2003-2017 IPT – Intellectual Products & Technologies Ltd. All rights reserved.

Full-stack Development with Node.js and React.js

IPT – Intellectual Products & Technologieshttp://www.iproduct.org/

Redux Thunk Async Actions - /actions/counteer.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 34: Full-stack Development with Node.js and React.js http ...iproduct.org/wp-content/uploads/2017/05/IPT_React_2017_06.pdf · Full-stack Development with Node.js and React.js IPT –

Copyright © 2003-2017 IPT – Intellectual Products & Technologies Ltd. All rights reserved.

Full-stack Development with Node.js and React.js

IPT – Intellectual Products & Technologieshttp://www.iproduct.org/

16/02/2017 Slide 34

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 35: Full-stack Development with Node.js and React.js http ...iproduct.org/wp-content/uploads/2017/05/IPT_React_2017_06.pdf · Full-stack Development with Node.js and React.js IPT –

Copyright © 2003-2017 IPT – Intellectual Products & Technologies Ltd. All rights reserved.

Full-stack Development with Node.js and React.js

IPT – Intellectual Products & Technologieshttp://www.iproduct.org/

16/02/2017 Slide 35

Thanks for Your Attention!

Questions?