SlideShare a Scribd company logo
React & Redux
Christoffer Noring
Google Developer Expert
Contents
React basics
Flux
Redux
CSS
Mixins
Router
Tooling and Best Practices covered by
Fabrice and Mathieu
React Basics
React lib
React.createClass({})
class Component extends React.Component
React DOM
ReactDOM.render(
[Component]/ [JSX Expression],
[element]
)
Render our app
Minimum Setup ES5
<script src="node_modules/react/dist/react.js"></script>
<script src="node_modules/react-dom/dist/react-dom.js"></script>
<script src=“https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.34/browser.min.js">
script>
<body>
<div id="example"></div>
<script type="text/babel">
ReactDOM.render(
);
</script>
</body>
<h1>Hello, world!</h1>,
document.getElementById('example')
Where to render
the appContent
JSX
Syntax extension to javascript
const element = <h1>Hello, world!</h1>;
Allows us to do things like:
Needs to be transpiled :
const element = (
<h1 className="greeting">
Hello, world!
</h1>
);
JSX
const element = React.createElement(
'h1',
{className: 'greeting'},
'Hello, world!'
);
ES5
JSX is your friend, you don’t have to use it
HTML in my javascript!!
Components
ES5 : React.createClass({})
Your first component
app.js index.html
var App = React.createClass({
render: function() {
return (
<div className="app">
Hello, world! I am an app component
</div>
);
}
});
ReactDOM.render(
<App />,
document.getElementById('example')
);
render() is like
a paint method
<body>
<div id="example"></div>
<script type="text/babel">
</script>
</body>
<h1>Hello, world!</h1>,
document.getElementById('examp
ReactDOM.render(
);
<script type="text/babel"
src="app.js"></script>
replace with
createClass(),
creates the component
Your second component
var CV = React.createClass({
render: function() {
return (
<div className="comments">
Showing your cv
</div>
);
}
});
var App = React.createClass({
render: function() {
return (
<CV />
);
}
});
Component within a component = component centric
programming
Call createClass() again
return CV component
from App component
Component, input
<Component prop={ data }>
this.props.prop
Component with data
let data = {
name : 'chris',
profession : 'software developer',
skills : ['.net', 'javascript', 'angular', 'react']
}
This is what we want to render
looks like a property
looks like a list
ReactDOM.render(
<App data={ data } />,
document.getElementById('example')
);
property = { variable }
Access data inside component like this:
var App = React.createClass({
render: function() {
return (
<div> { this.props.data.name } </div>
);
}
});
this.props.data.name
“chris”
Rendering a list
var App = React.createClass({
render: function() {
return (
<div>
<div> { this.props.data.name } </div>
<div>{ skills }</div>
</div>
);
}
});
let skills = this.props.data.skills.map(skill => {
return (
<div className="skill">{skill}</div>
);
});
Projection
Interpolation
Everything is in the “App” component = BAD
Refactoring
Putting everything in the App component isn’t very “react like”
of us
var App = React.createClass({
render: function() {
return (
<CV data={ this.props.data } />
);
}
});
var CV = React.createClass({
render: function() {
return (
<div className="cv">
{ this.data.props.name }
<Skills data={ this.data.props.skills } >
</div>
);
}
});
var Skills = React.createClass({
render : function(){
var skills = this.props.data.map(function(skill) {
return (
<div className="skill">{skill}</div>
);
});
return(
<div className="skills">
<h2>Skills</h2>
{ skills }
</div>
);
}
})
We can do this even better
var Skills = React.createClass({
render : function(){
var skills = this.props.data.map(function(skill) {
return (
<Skill data={ skill } />
);
});
return(
<div className="skills">
<h2>Skills</h2>
{ skills }
</div>
);
}
})
var Skill = React.createClass({
render : function(){
return(
<div className="skills">
<h3>{ this.props.data }</h3>
</div>
);
}
})
A component should do one thing well
One Skill comp
per skill item
Component tree so far
App
CV
Skills
Skill
Skill
Skill
etc…
What about methods?
<button type="submit"
onClick={this.onSubmit} >
Save new skills
</button>
var CV = React.createClass({
onSubmit : function(e){
e.preventDefault();
// do stuff
},
render : function(){
return (
)
}
Add method to
our object literal
Refer to method in
markup
State
Component State
var App = React.createClass({
getInitialState : function() {
return {
a : ‘some state’
};
},
render : function() {
return <div>{ this.state.a }</div>
}
});
Reading state
getInitialState is read
once per bootstrap,
define your state here
this.state.<prop>
Changing state
var App = React.createClass({
getInitialState : function() {
return {
newSkill : ‘some state’,
b : ‘some other state’
};
},
render : function() {
return <div>
<input value={this.state.newSkill} >
{ this.state.a }
</div>
}
For every change
of input field
update state
onChange={this.onSkillChange}
bind to onchange
onSkillChange : function(e){
this.setState({newSkill : e.target.value});
}
State summary
getInitialState(){ return { prop : ‘’ } }
{ this.state.prop }
this.setState({ prop : ‘newValue’ })
Lifecycle events
Initial State Changes Props changes
Unmounting
Initial
getDefaultProps
getInitialState
componentWillMount
render
componentDidMount
Set initial values
access DOM
fetch data
State changes
shouldComponentUpdate
componentWillUpdate
render
componentDidUpdate
boolean : is rerendering needed
prepare for update
perform DOM operations
Props change
componentWillReceiveProps
shouldComponentUpdate
componentWillUpdate
render
componentDidUpdate
called only when props
have changed
perform DOM operations
Unmounting
componentWillUnmount
is called before component is removed from DOM
do cleanup, think of it as a destructor
ES6
We want to write in ES6 cause it has nice features
Object.assign() Let Const
Spread Operator Lambdas
ES6 modules
import {} from ‘’
export default
export { a,b,c }
ES6 component
class Todo extends React.Component {
constructor(){
super();
this.action = this.action.bind(this);
this.state.prop = value
}
render() {
return (
<div onClick={this.action}>{this.props.title}</div>
)
}
action(e){
this.props.click( this.props.id );
}
}
GOTCHA, we need to call the following,
for our methods to be picked up
We inherit from React.Component
instead of
calling React.createClass({})
Otherwise its business as usual
we DON’t use getInitialState(){}
we just set this.state in constructor
We create a proper class
rather than an object literal
PropTypes
Catch bugs with type checking
Will give an error in a tool,
wrong type
Component.propTypes ={
title : React.PropTypes.string
}
<Component title=1 >
Example 1 - wrong type
Component.propTypes ={
title : React.PropTypes.string.isRequired
}
Example 2 - required
<Component > Will giver error, prop missing
Many validation types
oneOfType oneOf
arrayOf
objectOf
element instanceOf
symbol
custom
Further reading, https://facebook.github.io/react/docs/
typechecking-with-proptypes.html
Flux
Architecture pattern by Facebook
Action describes what
should happen with what data
Action
Dispatcher
Store
React e.g. Add todo
Store notifies listener that data
has changed and needs to be reread
Dispatch action to store, tell the store
Unidirectional flow, everything flows in one direction
Action
Dispatcher
Store
React
{ type : ADD_TODO, todo : { title : ‘dfdfd’ } }
What Payload
Dispatcher
Action
Dispatcher
Store
React
Dispatches actions dispatch(action)
Handles a dispatched action through
register(function(action){})
Store
Action
Dispatcher
Store
React
Contains your state, usually
same file have ability to perform
ajax and also notify listeners when
state has been updated
var Todos = React.createClass({
getInitialState : function(){
return { todos : Store.getTodos() }
}
render : function(){
return ([ render todos ])
},
})
//todos-component.js
componentDidMount : function(){
Store.addChangeListener( this._onChange )
},
componentWillUnmount : function(){
Store.removeChangeListener( this._onChange )
},
onChange() {
this.setState({ todos : Store.getTodos() })
}
Get data
1
Update state
so render() is called
2
store.js
var todos = [];
function loadTodos(){ return todos; }
var Store = merge(EventEmitter.prototype, {
getTodos : function(){ return todos; }
emitChange : function(){ emit(‘change’) },
addChangeListener : function(callback){ this.on(‘change’, callback) },
removeChangeListener : function(callback) { this.removeListener(‘change’, callback) }
})
Dispatcher.register(function(payload){
var action = payload.action;
switch(action) {
case ADD_TODO: todos.push( payload.data )
case LOAD_TODOS: loadTodos();
}
Store.emitChange();
})
Calls _onChange() on the component
Called when
Dispatcher.dispatch()
getData
addListener
removeListener
notifyChange
var AddTodo = React.createClass({
render : function(){
return ([ todo input ])
},
createTodo : function(todo){
Actions.addTodo( todo )
}
})
//add-todo-component.js
Calls the ActionCreator with a type and a payload
ActionCreator
Actions = {
addTodo : function(todo) {
Dispatcher.dispatch(
{ actionType : ADD_TODO, data : todo } )
}
…
}
Dispatch the action
Redux
Why Redux or
Flux growing pains
Scales well on larger complex apps
Boiler plate is way too big on smaller apps
Data flow
Action
Store
React
Reducers
No dispatcher!!
Action
Action
Store
React
Reducers
function addTodo( todo ) {
return { type : ‘ADD_TODO’, todo: todo }
}
Action Creator
Represent user intent
Must have a type
Redux Store
store.dispatch( action );
store.subscribe( listener );
store.getState()
replaceReducer( nextReducer )
Action
Store
React
Reducers
Reducers
Action
Store
React
Reducers
function reducer(state, action) {
return newState;
}
(state, action) => state
Must be pure
Multiple reducers per app
We want to change the state, without mutating so how?
Change object
Change Array
Change Object
What about a large object hierarchy?
Object.assign( target, oldObject, newState )
Object.assign(
{},
{ update : false, name : ‘’ },
{ update : true }
)
{ update : true, name : ‘’ }
Merged
Changing array
//mutable
state = [ { id : 1, name : 'tomato' } ]
state.push( { id: 2, name : 'cucumber' } );
return state;
Mutating
Point of mutation
//immutable
state = [
{ id : 1, name : 'tomato' }
]
return [
...state,
Object.assign({}, state, course)
]
Immutable
old array
+
new item
Spread operator …
Reducer no-no list
Mutate arguments
Perform side effects
Call non-pure functions
Benefits to immutable state
Clarity answers - who changed that state?
Mutable, anyone could have changed it
Immutable, only a reducer could have changed it
Performance
No need to check every single property on an object
if(oldState != newState), reference check
Time travel debugging
State Summary
ES5
lodash merge
lodash extend
Object-assign ( NPM )
Reference checking
is super fast
Enables time-travel
debugging
through browser plugin
Object.assign()
… spread operator for arrays
ES6
Change state by
All Reducers are called on each dispatch
addItemReducer
removeItemReducer
listItemsReducer
Dispatching addItem
{ type: ADD_ITEM, : item : item }
returns new state
return state
return state
Connect Redux to our App
react-redux
Action
Store
React
Reducers
Provider, attaches app to store
Connect, creates container items
Connect store data to our
app
ComponentApp
Provider
Store Data
Setup our store
Wrap App component in a Provider
import { combineReducers } from 'redux';
import todos from './todo-reducer';
const rootReducer = combineReducers({
todos : todos
}) // OR todos only, LHS is implied
export default rootReducer;
reducers/index.js
Root reducer
Combines all reducers in one,
this is one we feed to the store
Initialise store
import { createStore, applyMiddleware } from 'redux';
import rootReducer from '../reducers' // index.js
import reduxImmutableStateInvariant from 'redux-immutable-state-invariant';
export default function configureStore(initialState) {
return createStore(
rootReducer,
initialState,
applyMiddleware( reduxImmutableStateInvariant() )
)
}
configure-store.js
Create store
give it a
root reducer
initial state
and add middleware
Provider
<Provider store={store} >
<App />
</Provider>
Uses Reacts context - don’t touch
import configureStore from './store/configureStore';
import { Provider } from 'ReactRedux';
Make your store available to all your components
Component
Wrap our component in a container
component using
Connect
Presentational
Component
Container component
export default connect(
mapStateToProps,
mapDispatchToProps
)( PresentationalComponent )
what state
what functions
what state should I expose as props
mapStateToProps
mapStateToProps = () => {
return {
appState : ‘’,
otherAppState : ‘’
}
}
// Component
this.props.appState
this.props.otherAppState
Every time a change happens this function is rerun, so don’t
do anything expensive in there
mapDispatchToProps cont..
mapDispatchToProps = (dispatch) {
return {
loadTodos : () => {
dispatch( loadTodos() );
},
addTodo : (todo) => {
dispatch( addTodo(todo) );
}
}
}
Manual approach, but clear whats happening, recommended
when starting out
e.g. this.props.loadTodos();
mapDispatchToProps - nicer
what actions do we want to expose to the component
mapDispatchToProps = () => {
return {
actions : bindActionCreators(actions, dispatch)
}
}
This is a shorthand using Redux
this.actions.methodName()
Container component
Smart component
Focus on how things work
“Aware” of Redux
Subscribe to Redux state
Dispatch redux actions
react-redux lib
Presentational component
Normal component that show data through props,
knows nothing about Redux
Presentation component gets decorated
class TodoComponent extends React.Component{
onSave(){
this.props.dispatch(todoActions.addTodo(this.state.todo));
//console.log(this.state.todo.title);
}
}
function mapStateToProps(state, ownProps) {
return {
todos : state.todos
}
}
export default connect(
mapStateToProps)
(TodoComponent); 1
2
3
Reduxify your component in 3 steps
Decorate our Component
Expose state
Calling and dispatching
an action
Redux flow so far
Actions Dispatches an action
Reducers
current state + action =
new state
Store let connected components
know of state change
ReactRedux determine wether
to tell React to update UI
React new data passed
through props
YES
Something happenedReact
Redux concepts so far
Container and Presentation components
Has methods,
Has state,
Knows Redux
Just props
No Redux
ReactRedux
Provider Pass store data to Components
Connect
mapStateToProps Pass state and
methods to Components
mapDispatchToProps
Code Demo
Improving our Redux
Change our call to .connect()
export default connect(
mapStateToProps)
(TodoComponent);
export default connect(
mapStateToProps
mapDispatchToProps)
(TodoComponent);
function mapDispatchToProps(dispatch) {
return addTodo : todo => dispatch(todoActions.addTodo(todo))
}
Wrap the action in a dispatch()
onSave(){
this.props.dispatch(todoActions.addTodo(this.state.todo));
}
Change to
onSave(){
this.props.addTodo(this.state.todo));
}
All knowledge of dispatch is removed
Much cleaner
Dispatch() is no longer injected into the component
Fixing the component
And a little more…
import { bindActionCreators } from ‘redux’
This
function mapDispatchToProps(dispatch) {
return addTodo : todo => dispatch(todoActions.addTodo(todo))
}
Becomes this
function mapDispatchToProps(dispatch) {
return actions : bindActionCreators( todoActions, dispatch )
}
MAGIC !!
onSave(){
this.props.actions.addTodo(this.state.todo));
}
Clean up magic strings
export default {
ADD_TODO : 'ADD_TODO'
}
actionTypes.js
todo-actions.js
import actionTypes from './action-types';
function addTodo(todo) {
return { type : actionTypes.ADD_TODO, todo : todo };
}
todo-reducer.js
export default function todoReducer(state = [], action) {
switch(action.type) {
case actionTypes.ADD_TODO:
return [
...state,
Object.assign({}, action.todo)
]
And so on…
Replace string with constant
Async load
export function loadTodos() {
return function(dispatch) {
return service.getTodos().then( todos => {
dispatch( loadTodosSuccess(todos) )
}).catch(error => { console.error(error) })
}
}
export function loadTodosSuccess(todos) {
return { type : types.LOAD_TODOS, todos : todos }
}
todo-actions.js
index.js
const store = configureStore();
store.dispatch( loadTodos() )
set initial data
Call dispatch
when Ajax is done
export default function todoReducer(
state = [], action) {
switch(action.type) {
…
case actionTypes.LOAD_TODOS :
return action.todos
default :
return state;
}
}
todo-reducer.js
Component
class TodoComponent extends React.Component{
render(){
let todos = this.state.todos.map( todo => {
return <div>{ todo }</div>
})
return ( <div>{ todos }</div> )
}
}
function mapStateToProps(state, ownProps) {
return {
todos : state.todos
}
}
export default connect(
mapStateToProps)
(TodoComponent);
Async load summary
Create async action that calls
dispatch when done
Add reducer for loading data
Add said reducer to rootReducer
store.dispatch( loadAction() ) in index.js
ensure its exposed in mapStateToProps
use in presentation component
Thank you

More Related Content

What's hot (20)

PPTX
React JS - A quick introduction tutorial
Mohammed Fazuluddin
 
PPTX
Spring Boot Tutorial
Naphachara Rattanawilai
 
PPTX
React hooks
Assaf Gannon
 
PDF
ReactJS Tutorial For Beginners | ReactJS Redux Training For Beginners | React...
Edureka!
 
PPTX
React workshop
Imran Sayed
 
PPTX
Spring Boot
Jiayun Zhou
 
PPTX
React js
Nikhil Karkra
 
PPTX
Introduction to React
Rob Quick
 
PDF
What Is React | ReactJS Tutorial for Beginners | ReactJS Training | Edureka
Edureka!
 
PDF
Introduction to RxJS
Brainhub
 
PDF
React JS - Introduction
Sergey Romaneko
 
PDF
Introduction to Redux
Ignacio Martín
 
PPTX
Intro to React
Eric Westfall
 
PPTX
React + Redux Introduction
Nikolaus Graf
 
PDF
Full Stack React Workshop [CSSC x GDSC]
GDSC UofT Mississauga
 
PDF
Spring Boot
Pei-Tang Huang
 
PPTX
React.js - The Dawn of Virtual DOM
Jimit Shah
 
PPTX
reactJS
Syam Santhosh
 
PPTX
Introduction to react and redux
Cuong Ho
 
PDF
NEXT.JS
Binumon Joseph
 
React JS - A quick introduction tutorial
Mohammed Fazuluddin
 
Spring Boot Tutorial
Naphachara Rattanawilai
 
React hooks
Assaf Gannon
 
ReactJS Tutorial For Beginners | ReactJS Redux Training For Beginners | React...
Edureka!
 
React workshop
Imran Sayed
 
Spring Boot
Jiayun Zhou
 
React js
Nikhil Karkra
 
Introduction to React
Rob Quick
 
What Is React | ReactJS Tutorial for Beginners | ReactJS Training | Edureka
Edureka!
 
Introduction to RxJS
Brainhub
 
React JS - Introduction
Sergey Romaneko
 
Introduction to Redux
Ignacio Martín
 
Intro to React
Eric Westfall
 
React + Redux Introduction
Nikolaus Graf
 
Full Stack React Workshop [CSSC x GDSC]
GDSC UofT Mississauga
 
Spring Boot
Pei-Tang Huang
 
React.js - The Dawn of Virtual DOM
Jimit Shah
 
reactJS
Syam Santhosh
 
Introduction to react and redux
Cuong Ho
 

Viewers also liked (20)

PPTX
Rxjs ngvikings
Christoffer Noring
 
PDF
React + Redux for Web Developers
Jamal Sinclair O'Garro
 
PPTX
Rxjs swetugg
Christoffer Noring
 
PPTX
Rxjs ppt
Christoffer Noring
 
PDF
React JS and why it's awesome
Andrew Hull
 
PDF
Quick start with React | DreamLab Academy #2
DreamLab
 
PPTX
Typescript barcelona
Christoffer Noring
 
PPTX
Angular modules in depth
Christoffer Noring
 
PPTX
Finjs - Angular 2 better faster stronger
Christoffer Noring
 
PPTX
Angular2 rxjs
Christoffer Noring
 
PPTX
Angular2 + rxjs
Christoffer Noring
 
PDF
React 101
Casear Chu
 
PPTX
006. React - Redux framework
Binh Quan Duc
 
PPTX
007. Redux middlewares
Binh Quan Duc
 
PPTX
Rethinking Best Practices
floydophone
 
PPTX
Nativescript with angular 2
Christoffer Noring
 
PDF
Intellettuali Stranieri a Roma dal Grand Tour al XIX Secolo - 1a parte
Portante Andrea
 
PDF
Training lubricants and lubrication wtrpr 2017
M Hussam Adeni
 
PPTX
Digitalisaation merkitys turvallisuudelle
Jyrki Kasvi
 
PDF
Let's discover React and Redux with TypeScript
Mathieu Savy
 
Rxjs ngvikings
Christoffer Noring
 
React + Redux for Web Developers
Jamal Sinclair O'Garro
 
Rxjs swetugg
Christoffer Noring
 
React JS and why it's awesome
Andrew Hull
 
Quick start with React | DreamLab Academy #2
DreamLab
 
Typescript barcelona
Christoffer Noring
 
Angular modules in depth
Christoffer Noring
 
Finjs - Angular 2 better faster stronger
Christoffer Noring
 
Angular2 rxjs
Christoffer Noring
 
Angular2 + rxjs
Christoffer Noring
 
React 101
Casear Chu
 
006. React - Redux framework
Binh Quan Duc
 
007. Redux middlewares
Binh Quan Duc
 
Rethinking Best Practices
floydophone
 
Nativescript with angular 2
Christoffer Noring
 
Intellettuali Stranieri a Roma dal Grand Tour al XIX Secolo - 1a parte
Portante Andrea
 
Training lubricants and lubrication wtrpr 2017
M Hussam Adeni
 
Digitalisaation merkitys turvallisuudelle
Jyrki Kasvi
 
Let's discover React and Redux with TypeScript
Mathieu Savy
 
Ad

Similar to React lecture (20)

PDF
Why react matters
ShihChi Huang
 
PDF
React & Redux
Federico Bond
 
PPTX
React + Flux = Joy
John Need
 
PDF
Stay with React.js in 2020
Jerry Liao
 
PDF
React for Dummies
Mitch Chen
 
PPTX
React, Flux and a little bit of Redux
Ny Fanilo Andrianjafy, B.Eng.
 
PPTX
ReactJS Code Impact
Raymond McDermott
 
PDF
Reactивная тяга
Vitebsk Miniq
 
PPTX
React & Redux for noobs
[T]echdencias
 
PDF
The Road To Redux
Jeffrey Sanchez
 
PDF
Integrating React.js with PHP projects
Ignacio Martín
 
PPTX
React JS; all concepts. Contains React Features, JSX, functional & Class comp...
Karmanjay Verma
 
PDF
ReactJS - A quick introduction to Awesomeness
Ronny Haase
 
PPTX
Dyanaimcs of business and economics unit 2
jpm071712
 
PDF
2018 05-16 Evolving Technologies: React, Babel & Webpack
Codifly
 
PPTX
[Final] ReactJS presentation
洪 鹏发
 
PPT
ReactJS.ppt
MOMEKEMKUEFOUETDUREL
 
PPTX
Reactjs notes.pptx for web development- tutorial and theory
jobinThomas54
 
PDF
ReactJS presentation
Thanh Tuong
 
PDF
Welcome to React & Flux !
Ritesh Kumar
 
Why react matters
ShihChi Huang
 
React & Redux
Federico Bond
 
React + Flux = Joy
John Need
 
Stay with React.js in 2020
Jerry Liao
 
React for Dummies
Mitch Chen
 
React, Flux and a little bit of Redux
Ny Fanilo Andrianjafy, B.Eng.
 
ReactJS Code Impact
Raymond McDermott
 
Reactивная тяга
Vitebsk Miniq
 
React & Redux for noobs
[T]echdencias
 
The Road To Redux
Jeffrey Sanchez
 
Integrating React.js with PHP projects
Ignacio Martín
 
React JS; all concepts. Contains React Features, JSX, functional & Class comp...
Karmanjay Verma
 
ReactJS - A quick introduction to Awesomeness
Ronny Haase
 
Dyanaimcs of business and economics unit 2
jpm071712
 
2018 05-16 Evolving Technologies: React, Babel & Webpack
Codifly
 
[Final] ReactJS presentation
洪 鹏发
 
Reactjs notes.pptx for web development- tutorial and theory
jobinThomas54
 
ReactJS presentation
Thanh Tuong
 
Welcome to React & Flux !
Ritesh Kumar
 
Ad

More from Christoffer Noring (20)

PPTX
Azure signalR
Christoffer Noring
 
PPTX
Game dev 101 part 3
Christoffer Noring
 
PPTX
Game dev 101 part 2
Christoffer Noring
 
PPTX
Game dev workshop
Christoffer Noring
 
PPTX
Deploying your static web app to the Cloud
Christoffer Noring
 
PPTX
IaaS with ARM templates for Azure
Christoffer Noring
 
PPTX
Learning Svelte
Christoffer Noring
 
PPTX
Ng spain
Christoffer Noring
 
PDF
Angular Schematics
Christoffer Noring
 
PDF
Design thinking
Christoffer Noring
 
PDF
Keynote ijs
Christoffer Noring
 
PDF
Vue fundamentasl with Testing and Vuex
Christoffer Noring
 
PDF
Ngrx slides
Christoffer Noring
 
PDF
Kendoui
Christoffer Noring
 
PPTX
Angular mix chrisnoring
Christoffer Noring
 
PDF
Nativescript angular
Christoffer Noring
 
PDF
Graphql, REST and Apollo
Christoffer Noring
 
PDF
Angular 2 introduction
Christoffer Noring
 
PDF
Rxjs vienna
Christoffer Noring
 
PPTX
Rxjs marble-testing
Christoffer Noring
 
Azure signalR
Christoffer Noring
 
Game dev 101 part 3
Christoffer Noring
 
Game dev 101 part 2
Christoffer Noring
 
Game dev workshop
Christoffer Noring
 
Deploying your static web app to the Cloud
Christoffer Noring
 
IaaS with ARM templates for Azure
Christoffer Noring
 
Learning Svelte
Christoffer Noring
 
Angular Schematics
Christoffer Noring
 
Design thinking
Christoffer Noring
 
Keynote ijs
Christoffer Noring
 
Vue fundamentasl with Testing and Vuex
Christoffer Noring
 
Ngrx slides
Christoffer Noring
 
Angular mix chrisnoring
Christoffer Noring
 
Nativescript angular
Christoffer Noring
 
Graphql, REST and Apollo
Christoffer Noring
 
Angular 2 introduction
Christoffer Noring
 
Rxjs vienna
Christoffer Noring
 
Rxjs marble-testing
Christoffer Noring
 

Recently uploaded (20)

PDF
Newgen 2022-Forrester Newgen TEI_13 05 2022-The-Total-Economic-Impact-Newgen-...
darshakparmar
 
PDF
How Startups Are Growing Faster with App Developers in Australia.pdf
India App Developer
 
PPTX
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
PPTX
WooCommerce Workshop: Bring Your Laptop
Laura Hartwig
 
PDF
Biography of Daniel Podor.pdf
Daniel Podor
 
PPTX
Webinar: Introduction to LF Energy EVerest
DanBrown980551
 
PDF
What Makes Contify’s News API Stand Out: Key Features at a Glance
Contify
 
PDF
CIFDAQ Market Insights for July 7th 2025
CIFDAQ
 
PDF
Empower Inclusion Through Accessible Java Applications
Ana-Maria Mihalceanu
 
PDF
Mastering Financial Management in Direct Selling
Epixel MLM Software
 
PDF
HubSpot Main Hub: A Unified Growth Platform
Jaswinder Singh
 
PDF
Blockchain Transactions Explained For Everyone
CIFDAQ
 
PDF
July Patch Tuesday
Ivanti
 
PPTX
AUTOMATION AND ROBOTICS IN PHARMA INDUSTRY.pptx
sameeraaabegumm
 
PDF
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
PDF
Newgen Beyond Frankenstein_Build vs Buy_Digital_version.pdf
darshakparmar
 
PPTX
From Sci-Fi to Reality: Exploring AI Evolution
Svetlana Meissner
 
PDF
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
Fwdays
 
PDF
The Rise of AI and IoT in Mobile App Tech.pdf
IMG Global Infotech
 
PDF
From Code to Challenge: Crafting Skill-Based Games That Engage and Reward
aiyshauae
 
Newgen 2022-Forrester Newgen TEI_13 05 2022-The-Total-Economic-Impact-Newgen-...
darshakparmar
 
How Startups Are Growing Faster with App Developers in Australia.pdf
India App Developer
 
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
WooCommerce Workshop: Bring Your Laptop
Laura Hartwig
 
Biography of Daniel Podor.pdf
Daniel Podor
 
Webinar: Introduction to LF Energy EVerest
DanBrown980551
 
What Makes Contify’s News API Stand Out: Key Features at a Glance
Contify
 
CIFDAQ Market Insights for July 7th 2025
CIFDAQ
 
Empower Inclusion Through Accessible Java Applications
Ana-Maria Mihalceanu
 
Mastering Financial Management in Direct Selling
Epixel MLM Software
 
HubSpot Main Hub: A Unified Growth Platform
Jaswinder Singh
 
Blockchain Transactions Explained For Everyone
CIFDAQ
 
July Patch Tuesday
Ivanti
 
AUTOMATION AND ROBOTICS IN PHARMA INDUSTRY.pptx
sameeraaabegumm
 
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
Newgen Beyond Frankenstein_Build vs Buy_Digital_version.pdf
darshakparmar
 
From Sci-Fi to Reality: Exploring AI Evolution
Svetlana Meissner
 
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
Fwdays
 
The Rise of AI and IoT in Mobile App Tech.pdf
IMG Global Infotech
 
From Code to Challenge: Crafting Skill-Based Games That Engage and Reward
aiyshauae
 

React lecture

  • 1. React & Redux Christoffer Noring Google Developer Expert
  • 2. Contents React basics Flux Redux CSS Mixins Router Tooling and Best Practices covered by Fabrice and Mathieu
  • 5. React DOM ReactDOM.render( [Component]/ [JSX Expression], [element] ) Render our app
  • 6. Minimum Setup ES5 <script src="node_modules/react/dist/react.js"></script> <script src="node_modules/react-dom/dist/react-dom.js"></script> <script src=“https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.34/browser.min.js"> script> <body> <div id="example"></div> <script type="text/babel"> ReactDOM.render( ); </script> </body> <h1>Hello, world!</h1>, document.getElementById('example') Where to render the appContent
  • 7. JSX Syntax extension to javascript const element = <h1>Hello, world!</h1>; Allows us to do things like: Needs to be transpiled : const element = ( <h1 className="greeting"> Hello, world! </h1> ); JSX const element = React.createElement( 'h1', {className: 'greeting'}, 'Hello, world!' ); ES5 JSX is your friend, you don’t have to use it HTML in my javascript!!
  • 9. Your first component app.js index.html var App = React.createClass({ render: function() { return ( <div className="app"> Hello, world! I am an app component </div> ); } }); ReactDOM.render( <App />, document.getElementById('example') ); render() is like a paint method <body> <div id="example"></div> <script type="text/babel"> </script> </body> <h1>Hello, world!</h1>, document.getElementById('examp ReactDOM.render( ); <script type="text/babel" src="app.js"></script> replace with createClass(), creates the component
  • 10. Your second component var CV = React.createClass({ render: function() { return ( <div className="comments"> Showing your cv </div> ); } }); var App = React.createClass({ render: function() { return ( <CV /> ); } }); Component within a component = component centric programming Call createClass() again return CV component from App component
  • 11. Component, input <Component prop={ data }> this.props.prop
  • 12. Component with data let data = { name : 'chris', profession : 'software developer', skills : ['.net', 'javascript', 'angular', 'react'] } This is what we want to render looks like a property looks like a list ReactDOM.render( <App data={ data } />, document.getElementById('example') ); property = { variable } Access data inside component like this: var App = React.createClass({ render: function() { return ( <div> { this.props.data.name } </div> ); } }); this.props.data.name “chris”
  • 13. Rendering a list var App = React.createClass({ render: function() { return ( <div> <div> { this.props.data.name } </div> <div>{ skills }</div> </div> ); } }); let skills = this.props.data.skills.map(skill => { return ( <div className="skill">{skill}</div> ); }); Projection Interpolation Everything is in the “App” component = BAD
  • 14. Refactoring Putting everything in the App component isn’t very “react like” of us var App = React.createClass({ render: function() { return ( <CV data={ this.props.data } /> ); } }); var CV = React.createClass({ render: function() { return ( <div className="cv"> { this.data.props.name } <Skills data={ this.data.props.skills } > </div> ); } }); var Skills = React.createClass({ render : function(){ var skills = this.props.data.map(function(skill) { return ( <div className="skill">{skill}</div> ); }); return( <div className="skills"> <h2>Skills</h2> { skills } </div> ); } })
  • 15. We can do this even better var Skills = React.createClass({ render : function(){ var skills = this.props.data.map(function(skill) { return ( <Skill data={ skill } /> ); }); return( <div className="skills"> <h2>Skills</h2> { skills } </div> ); } }) var Skill = React.createClass({ render : function(){ return( <div className="skills"> <h3>{ this.props.data }</h3> </div> ); } }) A component should do one thing well One Skill comp per skill item
  • 16. Component tree so far App CV Skills Skill Skill Skill etc…
  • 18. <button type="submit" onClick={this.onSubmit} > Save new skills </button> var CV = React.createClass({ onSubmit : function(e){ e.preventDefault(); // do stuff }, render : function(){ return ( ) } Add method to our object literal Refer to method in markup
  • 19. State
  • 20. Component State var App = React.createClass({ getInitialState : function() { return { a : ‘some state’ }; }, render : function() { return <div>{ this.state.a }</div> } }); Reading state getInitialState is read once per bootstrap, define your state here this.state.<prop>
  • 21. Changing state var App = React.createClass({ getInitialState : function() { return { newSkill : ‘some state’, b : ‘some other state’ }; }, render : function() { return <div> <input value={this.state.newSkill} > { this.state.a } </div> } For every change of input field update state onChange={this.onSkillChange} bind to onchange onSkillChange : function(e){ this.setState({newSkill : e.target.value}); }
  • 22. State summary getInitialState(){ return { prop : ‘’ } } { this.state.prop } this.setState({ prop : ‘newValue’ })
  • 23. Lifecycle events Initial State Changes Props changes Unmounting
  • 25. State changes shouldComponentUpdate componentWillUpdate render componentDidUpdate boolean : is rerendering needed prepare for update perform DOM operations
  • 27. Unmounting componentWillUnmount is called before component is removed from DOM do cleanup, think of it as a destructor
  • 28. ES6
  • 29. We want to write in ES6 cause it has nice features Object.assign() Let Const Spread Operator Lambdas ES6 modules import {} from ‘’ export default export { a,b,c }
  • 30. ES6 component class Todo extends React.Component { constructor(){ super(); this.action = this.action.bind(this); this.state.prop = value } render() { return ( <div onClick={this.action}>{this.props.title}</div> ) } action(e){ this.props.click( this.props.id ); } } GOTCHA, we need to call the following, for our methods to be picked up We inherit from React.Component instead of calling React.createClass({}) Otherwise its business as usual we DON’t use getInitialState(){} we just set this.state in constructor We create a proper class rather than an object literal
  • 32. Catch bugs with type checking Will give an error in a tool, wrong type Component.propTypes ={ title : React.PropTypes.string } <Component title=1 > Example 1 - wrong type Component.propTypes ={ title : React.PropTypes.string.isRequired } Example 2 - required <Component > Will giver error, prop missing
  • 33. Many validation types oneOfType oneOf arrayOf objectOf element instanceOf symbol custom Further reading, https://facebook.github.io/react/docs/ typechecking-with-proptypes.html
  • 35. Action describes what should happen with what data Action Dispatcher Store React e.g. Add todo Store notifies listener that data has changed and needs to be reread Dispatch action to store, tell the store Unidirectional flow, everything flows in one direction
  • 36. Action Dispatcher Store React { type : ADD_TODO, todo : { title : ‘dfdfd’ } } What Payload
  • 37. Dispatcher Action Dispatcher Store React Dispatches actions dispatch(action) Handles a dispatched action through register(function(action){})
  • 38. Store Action Dispatcher Store React Contains your state, usually same file have ability to perform ajax and also notify listeners when state has been updated
  • 39. var Todos = React.createClass({ getInitialState : function(){ return { todos : Store.getTodos() } } render : function(){ return ([ render todos ]) }, }) //todos-component.js componentDidMount : function(){ Store.addChangeListener( this._onChange ) }, componentWillUnmount : function(){ Store.removeChangeListener( this._onChange ) }, onChange() { this.setState({ todos : Store.getTodos() }) } Get data 1 Update state so render() is called 2
  • 40. store.js var todos = []; function loadTodos(){ return todos; } var Store = merge(EventEmitter.prototype, { getTodos : function(){ return todos; } emitChange : function(){ emit(‘change’) }, addChangeListener : function(callback){ this.on(‘change’, callback) }, removeChangeListener : function(callback) { this.removeListener(‘change’, callback) } }) Dispatcher.register(function(payload){ var action = payload.action; switch(action) { case ADD_TODO: todos.push( payload.data ) case LOAD_TODOS: loadTodos(); } Store.emitChange(); }) Calls _onChange() on the component Called when Dispatcher.dispatch() getData addListener removeListener notifyChange
  • 41. var AddTodo = React.createClass({ render : function(){ return ([ todo input ]) }, createTodo : function(todo){ Actions.addTodo( todo ) } }) //add-todo-component.js Calls the ActionCreator with a type and a payload
  • 42. ActionCreator Actions = { addTodo : function(todo) { Dispatcher.dispatch( { actionType : ADD_TODO, data : todo } ) } … } Dispatch the action
  • 43. Redux
  • 44. Why Redux or Flux growing pains Scales well on larger complex apps Boiler plate is way too big on smaller apps
  • 47. Action Store React Reducers function addTodo( todo ) { return { type : ‘ADD_TODO’, todo: todo } } Action Creator Represent user intent Must have a type
  • 49. store.dispatch( action ); store.subscribe( listener ); store.getState() replaceReducer( nextReducer ) Action Store React Reducers
  • 51. Action Store React Reducers function reducer(state, action) { return newState; } (state, action) => state Must be pure Multiple reducers per app We want to change the state, without mutating so how?
  • 53. Change Object What about a large object hierarchy? Object.assign( target, oldObject, newState ) Object.assign( {}, { update : false, name : ‘’ }, { update : true } ) { update : true, name : ‘’ } Merged
  • 54. Changing array //mutable state = [ { id : 1, name : 'tomato' } ] state.push( { id: 2, name : 'cucumber' } ); return state; Mutating Point of mutation //immutable state = [ { id : 1, name : 'tomato' } ] return [ ...state, Object.assign({}, state, course) ] Immutable old array + new item Spread operator …
  • 55. Reducer no-no list Mutate arguments Perform side effects Call non-pure functions
  • 56. Benefits to immutable state Clarity answers - who changed that state? Mutable, anyone could have changed it Immutable, only a reducer could have changed it Performance No need to check every single property on an object if(oldState != newState), reference check Time travel debugging
  • 57. State Summary ES5 lodash merge lodash extend Object-assign ( NPM ) Reference checking is super fast Enables time-travel debugging through browser plugin Object.assign() … spread operator for arrays ES6 Change state by
  • 58. All Reducers are called on each dispatch addItemReducer removeItemReducer listItemsReducer Dispatching addItem { type: ADD_ITEM, : item : item } returns new state return state return state
  • 59. Connect Redux to our App
  • 60. react-redux Action Store React Reducers Provider, attaches app to store Connect, creates container items
  • 61. Connect store data to our app ComponentApp Provider Store Data Setup our store Wrap App component in a Provider
  • 62. import { combineReducers } from 'redux'; import todos from './todo-reducer'; const rootReducer = combineReducers({ todos : todos }) // OR todos only, LHS is implied export default rootReducer; reducers/index.js Root reducer Combines all reducers in one, this is one we feed to the store
  • 63. Initialise store import { createStore, applyMiddleware } from 'redux'; import rootReducer from '../reducers' // index.js import reduxImmutableStateInvariant from 'redux-immutable-state-invariant'; export default function configureStore(initialState) { return createStore( rootReducer, initialState, applyMiddleware( reduxImmutableStateInvariant() ) ) } configure-store.js Create store give it a root reducer initial state and add middleware
  • 64. Provider <Provider store={store} > <App /> </Provider> Uses Reacts context - don’t touch import configureStore from './store/configureStore'; import { Provider } from 'ReactRedux'; Make your store available to all your components
  • 65. Component Wrap our component in a container component using Connect Presentational Component Container component export default connect( mapStateToProps, mapDispatchToProps )( PresentationalComponent ) what state what functions
  • 66. what state should I expose as props mapStateToProps mapStateToProps = () => { return { appState : ‘’, otherAppState : ‘’ } } // Component this.props.appState this.props.otherAppState Every time a change happens this function is rerun, so don’t do anything expensive in there
  • 67. mapDispatchToProps cont.. mapDispatchToProps = (dispatch) { return { loadTodos : () => { dispatch( loadTodos() ); }, addTodo : (todo) => { dispatch( addTodo(todo) ); } } } Manual approach, but clear whats happening, recommended when starting out e.g. this.props.loadTodos();
  • 68. mapDispatchToProps - nicer what actions do we want to expose to the component mapDispatchToProps = () => { return { actions : bindActionCreators(actions, dispatch) } } This is a shorthand using Redux this.actions.methodName()
  • 69. Container component Smart component Focus on how things work “Aware” of Redux Subscribe to Redux state Dispatch redux actions react-redux lib
  • 70. Presentational component Normal component that show data through props, knows nothing about Redux Presentation component gets decorated
  • 71. class TodoComponent extends React.Component{ onSave(){ this.props.dispatch(todoActions.addTodo(this.state.todo)); //console.log(this.state.todo.title); } } function mapStateToProps(state, ownProps) { return { todos : state.todos } } export default connect( mapStateToProps) (TodoComponent); 1 2 3 Reduxify your component in 3 steps Decorate our Component Expose state Calling and dispatching an action
  • 72. Redux flow so far Actions Dispatches an action Reducers current state + action = new state Store let connected components know of state change ReactRedux determine wether to tell React to update UI React new data passed through props YES Something happenedReact
  • 73. Redux concepts so far Container and Presentation components Has methods, Has state, Knows Redux Just props No Redux ReactRedux Provider Pass store data to Components Connect mapStateToProps Pass state and methods to Components mapDispatchToProps
  • 76. Change our call to .connect() export default connect( mapStateToProps) (TodoComponent); export default connect( mapStateToProps mapDispatchToProps) (TodoComponent); function mapDispatchToProps(dispatch) { return addTodo : todo => dispatch(todoActions.addTodo(todo)) } Wrap the action in a dispatch()
  • 77. onSave(){ this.props.dispatch(todoActions.addTodo(this.state.todo)); } Change to onSave(){ this.props.addTodo(this.state.todo)); } All knowledge of dispatch is removed Much cleaner Dispatch() is no longer injected into the component Fixing the component
  • 78. And a little more…
  • 79. import { bindActionCreators } from ‘redux’ This function mapDispatchToProps(dispatch) { return addTodo : todo => dispatch(todoActions.addTodo(todo)) } Becomes this function mapDispatchToProps(dispatch) { return actions : bindActionCreators( todoActions, dispatch ) } MAGIC !! onSave(){ this.props.actions.addTodo(this.state.todo)); }
  • 80. Clean up magic strings
  • 81. export default { ADD_TODO : 'ADD_TODO' } actionTypes.js todo-actions.js import actionTypes from './action-types'; function addTodo(todo) { return { type : actionTypes.ADD_TODO, todo : todo }; } todo-reducer.js export default function todoReducer(state = [], action) { switch(action.type) { case actionTypes.ADD_TODO: return [ ...state, Object.assign({}, action.todo) ] And so on… Replace string with constant
  • 83. export function loadTodos() { return function(dispatch) { return service.getTodos().then( todos => { dispatch( loadTodosSuccess(todos) ) }).catch(error => { console.error(error) }) } } export function loadTodosSuccess(todos) { return { type : types.LOAD_TODOS, todos : todos } } todo-actions.js index.js const store = configureStore(); store.dispatch( loadTodos() ) set initial data Call dispatch when Ajax is done
  • 84. export default function todoReducer( state = [], action) { switch(action.type) { … case actionTypes.LOAD_TODOS : return action.todos default : return state; } } todo-reducer.js
  • 85. Component class TodoComponent extends React.Component{ render(){ let todos = this.state.todos.map( todo => { return <div>{ todo }</div> }) return ( <div>{ todos }</div> ) } } function mapStateToProps(state, ownProps) { return { todos : state.todos } } export default connect( mapStateToProps) (TodoComponent);
  • 86. Async load summary Create async action that calls dispatch when done Add reducer for loading data Add said reducer to rootReducer store.dispatch( loadAction() ) in index.js ensure its exposed in mapStateToProps use in presentation component