KEMBAR78
Workshop 20: ReactJS Part II Flux Pattern & Redux | PDF
Front End Workshops
ReactJS - Part II
Flux Pattern & Redux
Cristina Hernández
Jordi Serra
ReactJS Summary
1. Decompose UI into reusable components which
render to virtual DOM
2. ReactJS will sync VDOM to real browser DOM
3. JSX format
4. Can render on client and server
ReactJS Summary - Component Types
const ButtonChange = ({update}) => {
return (
<button onClick={update}>
change
</button>
)
}
class Lannister extends React.
Component{
constructor(props) {
super(props);
this.state = {
motto: "Hear me roar"
};
}
render() {
return (
<div>
<h3>Lannister</h3>
name: {this.props.name} <br/>
motto: {this.state.motto} <br/>
</div>
);
}
}
Flux Pattern
Redux Framework
Predictable state container for JS apps
Redux Flow
Redux - Three Principles
1. Single Source of Truth
The whole application must be described solely using a single
object: state
2. State is Read-only
The only way to change state is to emit an action
3. Changes are made with Pure Functions
Reducers are pure functions → No other variables involved (in or
out)
All actions pass through all reducers → ensure state is consistent
IN STATE WE TRUST
State: Single Source of Truth
$> console.log(store.getState())
{
visibilityFilter: 'SHOW_ALL',
todos: [
{
text: 'Consider using Redux',
completed: true,
},
{
text: 'Keep all state in a single tree',
completed: false
}
]
}
State is read only
The only way to mutate the state
is to dispatch an action → an object
describing what happened
store.dispatch({
type: 'COMPLETE_TODO',
index: 1
})
store.dispatch({
type: 'SET_VISIBILITY_FILTER',
filter: 'SHOW_COMPLETED'
})
State after action
State before action
Changes are made with REDUCERS
Reducers are pure functions.
Actions pass through all reducers
Never mutate state. Always return a new one
import {
combineReducers,
createStore
} from 'redux'
let reducer = combineReducers({ visibilityFilter, todos })
let store = createStore(reducer)
Changes are made with REDUCERS
function todos(state = [], action) {
switch (action.type) {
case 'ADD_TODO':
return [...state, {
text: action.text,
completed: false
}]
case 'COMPLETE_TODO':
return state.map((todo, index) => {
if (index === action.index) {
return Object.assign({}, todo, {
completed: true
})
}
return todo
})
default:
return state
}
}
function visibilityFilter(state =
'SHOW_ALL', action) {
switch (action.type) {
case 'SET_VISIBILITY_FILTER':
return action.filter
default:
return state
}
}
Minions App
Connect React with Redux - mapStateToProps
import React, { Component } from 'react';
import { connect } from 'react-redux';
class MinionList extends Component {
createMinionMap() {
return this.props.minionList.map(minion => {
return (<MinionItem key={minion.id} minion={minion} />);
});
}
render() {
return (<ul className="col-md-10">{this.createMinionMap()}</ul>);
}
}
function mapStateToProps(state) {
return {
minionList: state.minionList
}
}
export default connect(mapStateToProps)(MinionList);
containers/minion_list.js
connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options]) - React-redux
Connects a React component to a Redux store.
It does not modify the component class passed to it. Instead, it returns a new, connected component class, for you to use.
Connect React with Redux - Dispatch Action
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { searchMinion } from '../actions/index';
class SearchBar extends Component {
render() {
return (
<div>
<input onChange={event => this.onInputChange(event.target.value)} />
</div>);
}
onInputChange(term) {
this.props.searchMinion(term);
}
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({ searchMinion }, dispatch);
}
export default connect(null, mapDispatchToProps)(SearchBar);
containers/search_bar.js
bindActionCreators(actionCreators, dispatch) - Redux
Turns an object whose values are action creators, into an object with the same keys, but with every action creator
wrapped into a dispatch call so they may be invoked directly.
Connect React with Redux - Define Action
export const SEARCH_ACTION = 'SEARCH_ACTION';
actions/types.js
import {
SEARCH_ACTION
} from '../actions/types';
export default function(state=[], action)
{
switch (action.type) {
case SEARCH_ACTION:
//return [action.payload, ...state];
return action.payload;
default:
return state;
}
}
reducers/minion_search.js
import {
SEARCH_ACTION
} from './types';
export function searchMinion(term) {
return {
type: SEARCH_ACTION,
payload: getMinionListByTerm(term)
}
}
actions/index.js
Connect React with Redux - Make store connectable
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import App from './components/app';
import rootReducer from './reducers';
ReactDOM.render(
<Provider
store={createStore(rootReducer)}>
<App />
</Provider>
,
document.querySelector('.container'));
index.js
import { combineReducers } from 'redux';
import minionList from './minion_search';
import minionSelect from './minion_select';
const rootReducer = combineReducers({
minionList: minionList, //minionList
minionSelect: minionSelect //minionSelect
});
export default rootReducer;
reducers/index.js
<Provider store> - React-redux
Makes the Redux store available to the connect() calls in the component hierarchy below.
Connect React with Redux - Make store connectable
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import App from './components/app';
import rootReducer from './reducers';
ReactDOM.render(
<Provider
store={createStore(rootReducer)}>
<App />
</Provider>
,
document.querySelector('.container'));
index.js
import { combineReducers } from 'redux';
import minionList from './minion_search';
import minionSelect from './minion_select';
const rootReducer = combineReducers({
minionList: minionList, //minionList
minionSelect: minionSelect //minionSelect
});
export default rootReducer;
reducers/index.js
createStore(reducer, [initialState], [enhancer]) - Redux
Creates a Redux store that holds the complete state tree of your app.
There should only be a single store in your app.
Connect React with Redux - Make store connectable
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import App from './components/app';
import rootReducer from './reducers';
ReactDOM.render(
<Provider
store={createStore(rootReducer)}>
<App />
</Provider>
,
document.querySelector('.container'));
index.js
import { combineReducers } from 'redux';
import minionList from './minion_search';
import minionSelect from './minion_select';
const rootReducer = combineReducers({
minionList: minionList, //minionList
minionSelect: minionSelect //minionSelect
});
export default rootReducer;
reducers/index.js
combineReducers(reducers) - Redux
The combineReducers helper function turns an object whose values are different reducing functions into a single
reducing function you can pass to createStore.
Workshop 20: ReactJS Part II Flux Pattern & Redux

Workshop 20: ReactJS Part II Flux Pattern & Redux

  • 1.
    Front End Workshops ReactJS- Part II Flux Pattern & Redux Cristina Hernández Jordi Serra
  • 2.
    ReactJS Summary 1. DecomposeUI into reusable components which render to virtual DOM 2. ReactJS will sync VDOM to real browser DOM 3. JSX format 4. Can render on client and server
  • 3.
    ReactJS Summary -Component Types const ButtonChange = ({update}) => { return ( <button onClick={update}> change </button> ) } class Lannister extends React. Component{ constructor(props) { super(props); this.state = { motto: "Hear me roar" }; } render() { return ( <div> <h3>Lannister</h3> name: {this.props.name} <br/> motto: {this.state.motto} <br/> </div> ); } }
  • 4.
  • 5.
    Redux Framework Predictable statecontainer for JS apps
  • 6.
  • 7.
    Redux - ThreePrinciples 1. Single Source of Truth The whole application must be described solely using a single object: state 2. State is Read-only The only way to change state is to emit an action 3. Changes are made with Pure Functions Reducers are pure functions → No other variables involved (in or out) All actions pass through all reducers → ensure state is consistent
  • 8.
    IN STATE WETRUST State: Single Source of Truth $> console.log(store.getState()) { visibilityFilter: 'SHOW_ALL', todos: [ { text: 'Consider using Redux', completed: true, }, { text: 'Keep all state in a single tree', completed: false } ] }
  • 9.
    State is readonly The only way to mutate the state is to dispatch an action → an object describing what happened store.dispatch({ type: 'COMPLETE_TODO', index: 1 }) store.dispatch({ type: 'SET_VISIBILITY_FILTER', filter: 'SHOW_COMPLETED' }) State after action State before action
  • 10.
    Changes are madewith REDUCERS Reducers are pure functions. Actions pass through all reducers Never mutate state. Always return a new one import { combineReducers, createStore } from 'redux' let reducer = combineReducers({ visibilityFilter, todos }) let store = createStore(reducer)
  • 11.
    Changes are madewith REDUCERS function todos(state = [], action) { switch (action.type) { case 'ADD_TODO': return [...state, { text: action.text, completed: false }] case 'COMPLETE_TODO': return state.map((todo, index) => { if (index === action.index) { return Object.assign({}, todo, { completed: true }) } return todo }) default: return state } } function visibilityFilter(state = 'SHOW_ALL', action) { switch (action.type) { case 'SET_VISIBILITY_FILTER': return action.filter default: return state } }
  • 12.
  • 13.
    Connect React withRedux - mapStateToProps import React, { Component } from 'react'; import { connect } from 'react-redux'; class MinionList extends Component { createMinionMap() { return this.props.minionList.map(minion => { return (<MinionItem key={minion.id} minion={minion} />); }); } render() { return (<ul className="col-md-10">{this.createMinionMap()}</ul>); } } function mapStateToProps(state) { return { minionList: state.minionList } } export default connect(mapStateToProps)(MinionList); containers/minion_list.js connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options]) - React-redux Connects a React component to a Redux store. It does not modify the component class passed to it. Instead, it returns a new, connected component class, for you to use.
  • 14.
    Connect React withRedux - Dispatch Action import React, { Component } from 'react'; import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; import { searchMinion } from '../actions/index'; class SearchBar extends Component { render() { return ( <div> <input onChange={event => this.onInputChange(event.target.value)} /> </div>); } onInputChange(term) { this.props.searchMinion(term); } } function mapDispatchToProps(dispatch) { return bindActionCreators({ searchMinion }, dispatch); } export default connect(null, mapDispatchToProps)(SearchBar); containers/search_bar.js bindActionCreators(actionCreators, dispatch) - Redux Turns an object whose values are action creators, into an object with the same keys, but with every action creator wrapped into a dispatch call so they may be invoked directly.
  • 15.
    Connect React withRedux - Define Action export const SEARCH_ACTION = 'SEARCH_ACTION'; actions/types.js import { SEARCH_ACTION } from '../actions/types'; export default function(state=[], action) { switch (action.type) { case SEARCH_ACTION: //return [action.payload, ...state]; return action.payload; default: return state; } } reducers/minion_search.js import { SEARCH_ACTION } from './types'; export function searchMinion(term) { return { type: SEARCH_ACTION, payload: getMinionListByTerm(term) } } actions/index.js
  • 16.
    Connect React withRedux - Make store connectable import React from 'react'; import ReactDOM from 'react-dom'; import { Provider } from 'react-redux'; import { createStore } from 'redux'; import App from './components/app'; import rootReducer from './reducers'; ReactDOM.render( <Provider store={createStore(rootReducer)}> <App /> </Provider> , document.querySelector('.container')); index.js import { combineReducers } from 'redux'; import minionList from './minion_search'; import minionSelect from './minion_select'; const rootReducer = combineReducers({ minionList: minionList, //minionList minionSelect: minionSelect //minionSelect }); export default rootReducer; reducers/index.js <Provider store> - React-redux Makes the Redux store available to the connect() calls in the component hierarchy below.
  • 17.
    Connect React withRedux - Make store connectable import React from 'react'; import ReactDOM from 'react-dom'; import { Provider } from 'react-redux'; import { createStore } from 'redux'; import App from './components/app'; import rootReducer from './reducers'; ReactDOM.render( <Provider store={createStore(rootReducer)}> <App /> </Provider> , document.querySelector('.container')); index.js import { combineReducers } from 'redux'; import minionList from './minion_search'; import minionSelect from './minion_select'; const rootReducer = combineReducers({ minionList: minionList, //minionList minionSelect: minionSelect //minionSelect }); export default rootReducer; reducers/index.js createStore(reducer, [initialState], [enhancer]) - Redux Creates a Redux store that holds the complete state tree of your app. There should only be a single store in your app.
  • 18.
    Connect React withRedux - Make store connectable import React from 'react'; import ReactDOM from 'react-dom'; import { Provider } from 'react-redux'; import { createStore } from 'redux'; import App from './components/app'; import rootReducer from './reducers'; ReactDOM.render( <Provider store={createStore(rootReducer)}> <App /> </Provider> , document.querySelector('.container')); index.js import { combineReducers } from 'redux'; import minionList from './minion_search'; import minionSelect from './minion_select'; const rootReducer = combineReducers({ minionList: minionList, //minionList minionSelect: minionSelect //minionSelect }); export default rootReducer; reducers/index.js combineReducers(reducers) - Redux The combineReducers helper function turns an object whose values are different reducing functions into a single reducing function you can pass to createStore.