ReactJS - webagesolutionsfiles.com · Reactjs Features • React is used for V in MVC. • React...
Transcript of ReactJS - webagesolutionsfiles.com · Reactjs Features • React is used for V in MVC. • React...
ReactJS
Mastering Reactjs and Redux
@Webage
ECMASCRIPT 6
• Variable types
• Arrow functions
• Modules
• Classes
• A lot more...
@Webage
Immutable Variables
• 1 const MY_CONSTANT = 1;
• 2 MY_CONSTANT = 2 // Error
• See the Statement in line 2 and you will see ECMA6 came up with concept of immutable variable.
@Webage
Using Block Scopes
@Webage
Lambda ARROW FUNCTIONS
@Webage
Arrow Function -2
@Webage
Arrow Function-3
@Webage
ECMA Modules
@Webage
ECMA Modules-2
@Webage
Working with ECMA Classes
@Webage
ECMA classes-2
@Webage
Using Spread Operators in ECMA6
@Webage
Spread Operator-2
@Webage
Babel
@Webage
ECMASCRIPT 6 Compatibility
• Browsers
– Support inconsistent between browsers. Microsoft Edge is one best in ES6 support. :-)
• Node
– Partial support. Some features are available only on versions > 5 and need to be explicitly enabled with a runtime flag.
@Webage
What is ReactJS
• Javascript Library to handle View Layer.
• Developed by Facebook.
• Helps in creating Decoupled reusable UI Components.
• Unique feature of Reactjs is its capability of working on client side and also rendering on server side.
• State change based rendering and Virtual DOM adds additional capability.
@Webage
Why Reactjs
• Focus on View Layer.
• Minimize DOM Manipulation.
• Declarative.
• Open Library.
• Community Support.
@Webage
Reactjs Features
• React is used for V in MVC.
• React treats everything as component.
• Code Maintenance is simple in component driven approach.
• React implements one way data flow .It simplifies app building.
• React uses Virtual DOM that improves performance as compared to regular DOM rendering.
@Webage
REACT.JS
Fundamentals
Objective
Overview
Components
JSX
Data for component
The component lifecycle
Component Methods
Component Breakdown
React v0.14
Flux (Intro)
React: Overview
A powerful framework by FB
❖ Implements a virtual DOM
❖ Allows us to render components super fast
❖ Removes any unnecessary overhead from DOM operations
❖ Deal with the "V" of any MVC framework
“The way we are able to figure this out is that React does
not manipulate the DOM unless it needs to.
It uses a fast, internal mock DOM to perform diffs and
computes the most efficient DOM mutation for you.”
- React Doc
❖ Implements a virtual DOM
❖ Allows us to render components super fast
❖ Removes any unnecessary overhead from DOM operations
❖ Deal with the "V" of any MVC framework
var msg = 'Bad';
$userMsg.html( '<p>I love Breaking ' + msg );
var data = {'user_id' : 13,'user_name' : 'W.W','user_msg' : 'I am the one who knocks!'
};
$chatList.append([
'<li class="chat__msg-wrap">','<img class="chat__user-img" src="' +
getUserImg(data.user_id) + '"/>','<span class="chat__user-name">' + data.user_name +
'</span>','<span class="chat__user-msg">' + data.user_msg +
'</span>','</li>'
].join(););
❖ Implements a virtual DOM
❖ Allows us to render components super fast
❖ Removes any unnecessary overhead from DOM operations
❖ Deal with the "V" of any MVC framework
var msg = 'Bad';
$userMsg.html( '<p>I love Breaking ' + msg );
var data = {'user_id' : 13,'user_name' : 'W.W','user_msg' : 'I am the one who knocks!'
};
$chatList.append([
'<li class="chat__msg-wrap">','<img class="chat__user-img" src="' +
getUserImg(data.user_id) + '"/>','<span class="chat__user-name">' + data.user_name +
'</span>','<span class="chat__user-msg">' + data.user_msg +
'</span>','</li>'
].join(););
Components
Special functionality unit
❖ Each component is contained in its own "scope"
❖ Define the functionality and reuse it as many times
❖ Has a render function, which returns the HTML the component will render in the
browser
❖ We can call other React component's too
JSX
HTML inside of JS
❖ Write HTML inside of Javascript without having to wrap strings around it
❖ We don't have to worry about strings and multiple lines etc
❖ Transform the JSX in the browser on runtime - not recommended as it slows down your page
❖ Both gulp and grunt offer a JSX transformer
$chatList.append( '<li class="chat__msg-wrap"> <img class="chat__user-img" src="' + getUserImg(data.user_id) + '"/><span class="chat__user-name">' + data.user_name + '</span> <span class="chat__user-msg">' + data.user_msg + '</span> </li>' );
$chatList.append('<li class="chat__msg-wrap">' +
'<img class="chat__user-img" src="' + getUserImg(data.user_id) + '"/>' +
'<span class="chat__user-name">' + data.user_name + '</span>' +
'<span class="chat__user-msg">' + data.user_msg + '</span>' +
'</li>');
$chatList.append([
'<li class="chat__msg-wrap">','<img class="chat__user-img" src="' +
getUserImg(data.user_id) + '"/>','<span class="chat__user-name">' + data.user_name +
'</span>','<span class="chat__user-msg">' + data.user_msg +
Using JSX
var ExampleComponent = React.createClass({render: function () {
return (<div className="navigation">
Hello World!</div>
);}
});
var ExampleComponent = React.createClass({render: function () {
return (React.createElement('div', {className: 'navigation'},
'Hello World!'));
}});
❖ You don't have to use JSX
❖ Using className since class is a reserved word in Javascript
❖ JSX transforms the code, changes all the attributes on the node into an object
Using variables for attributes
var ExampleComponent = React.createClass({render: function () {
var navigationClass = 'navigation';return (
<div className={ navigationClass }>Hello World!
</div>);
}});
❖ Dynamically change the class of a component
❖ Wrap it around a set of curly braces, so JSX knows that it is an external variable
The Initial Render
var ExampleComponent = React.createClass({render: function () {
var navigationClass = 'navigation';return (
<div className={ navigationClass }>Hello World!
</div>);
}});
ReactDOM.render( <ExampleComponent />, document.body );
❖ Tell React which component to render, and point to an existing DOM node for where to render it
Data for component
Props and States
Props
❖ Props is the data passed into a component
❖ Props is accessed via “this.props”
❖ Props is immutable, don’t change only use
var SayMyName = React.createClass({render: function () {
return (<div className="say-hello">
Hello { this.props.name }</div>
);}
});
var myName = 'Heisenberg';
ReactDOM.render(<SayMyName name={ myName } />, document.body);
var SayMyName = React.createClass({render: function () {
return (<div className="say-hello">
Hello { this.props.name }</div>
);}
});
var myName = 'Heisenberg';
ReactDOM.render(<SayMyName name={ myName } />, document.body);
var SayMyName = React.createClass({render: function () {
return (<div className="say-hello">
Hello { this.props.name }</div>
);}
});
var myName = 'Heisenberg';
ReactDOM.render(<SayMyName name={ myName } />, document.body);
State
❖ State is the private data within each instance of components
❖ State is accessed via “this.state”
❖ State is mutable, do whatever we want
❖ Usually we hook those data into state that represent UI
❖ Changing state will re-render UI
var SayMyName = React.createClass({getInitalState: function () {
return { greet: 'Hello' }},render: function () {
return (<div className="say-hello">
{ this.state.greet } { this.props.name }</div>
);}
});
var myName = 'Heisenberg';
ReactDOM.render(<SayMyName name={ myName } />, document.body);
The component lifecycle
getInitialState
only called once, and is called as the component is
being mounted.
componentWillMount
As soon as your component is about to be mounted,
this is called.
var ExampleComponent = React.createClass({componentWillMount: function () {
// hide any loading screens// remove any placeholders
},render: function () {
// this gets called many times in a components lifereturn (
<div>Hello World!
</div>);
}});
componentDidMount
Once your component has ran the render function
and actually rendered your component in the DOM
var ExampleComponent = React.createClass({componentDidMount: function () {
// render a chart on the DOM node// bind events to window, like resize
},render: function () {
return (<div>
Hello World!</div>
);}
});
componentWillUnmount
If you were to remove the component from the
DOM, this function is called
var ExampleComponent = React.createClass({componentWillUnmount: function () {
// unbind events to window, like resize},render: function () {
return (<div>
Hello World!</div>
);}
});
Component Methods
getDefaultProps
Define the default values for the properties of the
component that we are expecting
var Navigation = React.createClass({getDefaultProps: function () {
return {nav: {}
}},render: function () {
return (<ul className="navigation">...</ul>
);}
});
ReactDOM.render( <Navigation nav={ navObj } />, $header );ReactDOM.render( <Navigation />, $footer );
propTypes
Specify the type of each property we are expecting
for validation. Checked only in development mode.
var Navigation = React.createClass({propTypes: {
nav : React.PropTypes.object,data : React.PropTypes.array
},render: function () {
return (<ul className="navigation">...</ul>
);}
});
ReactDOM.render( <Navigation nav={ navObj } />, $header );
mixins
So we don't have to write the same code twice
var ExampleMixin = {componentDidMount: function () {
// bind resize event on window},componentWillUnmount: function () {
// unbind resize event from window}
};
var ExampleComponent = React.createClass({mixins: [ExampleMixin]
});
var AnotherComponent = React.createClass({mixins: [ExampleMixin]
});
Looping
Looping through data in array of objects
var Navigation = React.createClass({render: function () {
var items = this.props.nav.map(function (item) {return (
<li className="navigation__item"><a className="navigation__link" href={ item.href }>
{ item.text }</a>
</li>);
});
return (<ul className="navigation"> { items } </ul>
);}
});
var navObj = [{href: 'http://vijaydev.com',text: 'My Website'
}];
ReactDOM.render( <Navigation nav={ navObj } />, $header );
var Navigation = React.createClass({render: function () {
var items = this.props.nav.map(function (item) {return (
<li className="navigation__item"><a className="navigation__link" href={ item.href }>
{ item.text }</a>
</li>);
});
return (<ul className="navigation"> { items } </ul>
);}
});
var navObj = [{href: 'http://vijaydev.com',text: 'My Website'
}];
ReactDOM.render( <Navigation nav={ navObj } />, $header );
var Navigation = React.createClass({render: function () {
var items = this.props.nav.map(function (item) {return (
<li className="navigation__item"><a className="navigation__link" href={ item.href }>
{ item.text }</a>
</li>);
});
return (<ul className="navigation"> { items } </ul>
);}
});
var navObj = [{href: 'http://vijaydev.com',text: 'My Website'
}];
ReactDOM.render( <Navigation nav={ navObj } />, $header );
var NavItem = React.createClass({render: function () {
return (<li className="navigation__item">
<a className="navigation__link" href={ this.props.href }>{ this.props.text }
</a></li>
);}
});
var Navigation = React.createClass({render: function () {
var items = this.props.nav.map(function (item) {return (
<NavItem href={ item.href } text={ item.text } />);
});
return (<ul className="navigation">{ items }</ul>
);}
});
Component Breakdown
UI to reusable components
Case study: How to breakdown UI into various
reusable components
data = [{'src' : '/path/to/image','alt' : 'alt text of image','title' : 'name of the movie','href' : '/path/to/the/movie/details/page','cast' : ['array', 'of', 'movie', 'casts'],'rating' : 'movie rating','theater_href' : '/path/to/theater/list'
}, {......
}, {......
}];
props = [{
'src' : '/path/to/image','alt' : 'alt text of image','title' : 'name of the movie','href' : '/path/to/the/movie/details/page','cast' : ['array', 'of', 'movie', 'casts'],'rating' : 'movie rating','theater_href' : '/path/to/theater/list'
}, {...}, {...}];
state = {'actualData' : this.props,'currWidth' : 'calculated current screen width','colCount' : 'based on currWidth & max column count','perPage' : 'based on currWidth & colCount','totalPages' : 'based on perPage & actualData length','currPageNo' : 'used in calculating pageData','pageData' : 'based on totalPages & currPageNo'
};
<MoviePosterContent>
<MoviePosterList data={ this.state.pageData }>
<PosterItem data={ pageData[i] }>
<PosterNameCasts data={ iSrc, iAlt, iTitle, iHref, iCast } />
<PosterRatingTheater data={ iRating, itheaterHref } />
</PosterItem>
</MoviePosterList>
<Navigation data={ this.state.totalPages, this.state.currPageNo } />
</MoviePosterContent>
ReactDOM.render(<MoviePosterContent data={ data } />, $domNode);
<MoviePosterContent><MoviePosterList data={ this.state.pageData }>
<PosterItem data={ pageData[i] }><PosterNameCasts data={ iSrc, iAlt, iTitle, iHref, iCast } /><PosterRatingTheater data={ iRating, itheaterHref } />
</PosterItem></MoviePosterList>
<Navigation data={ this.state.totalPages, this.state.currPageNo } /></MoviePosterContent>
ReactDOM.render( <MoviePosterContent data={ data } />, $domNode );
<MoviePosterContent>
<MoviePosterList data={ this.state.pageData }>
<PosterItem data={ pageData[i] }>
<PosterNameCasts data={ iSrc, iAlt, iTitle, iHref, iCast } />
<PosterRatingTheater data={ iRating, itheaterHref } />
</PosterItem>
</MoviePosterList>
<Navigation data={ this.state.totalPages, this.state.currPageNo } />
</MoviePosterContent>
ReactDOM.render(<MoviePosterContent data={ data } />, $domNode);
<MoviePosterContent><MoviePosterList data={ this.state.pageData }>
<PosterItem data={ pageData[i] }><PosterNameCasts data={ iSrc, iAlt, iTitle, iHref, iCast } /><PosterRatingTheater data={ iRating, itheaterHref } />
</PosterItem></MoviePosterList>
<Navigation data={ this.state.totalPages, this.state.currPageNo } /></MoviePosterContent>
ReactDOM.render( <MoviePosterContent data={ data } />, $domNode );
props = [{
'src' : '/path/to/image','alt' : 'alt text of image','title' : 'name of the movie','href' : '/path/to/the/movie/details/page','cast' : ['array', 'of', 'movie', 'casts'],'rating' : 'movie rating','theater_href' : '/path/to/theater/list'
}, {...}, {...}];
state = {'actualData' : this.props,'currWidth' : 'calculated current screen width','colCount' : 'based on currWidth & max column count','perPage' : 'based on currWidth & colCount','totalPages' : 'based on perPage & actualData length','currPageNo' : 'used in calculating pageData','pageData' : 'based on totalPages & currPageNo'
};
<MoviePosterContent>
<MoviePosterList data={ this.state.pageData }>
<PosterItem data={ pageData[i] }>
<PosterNameCasts data={ iSrc, iAlt, iTitle, iHref, iCast } />
<PosterRatingTheater data={ iRating, itheaterHref } />
</PosterItem>
</MoviePosterList>
<Navigation data={ this.state.totalPages, this.state.currPageNo } />
</MoviePosterContent>
ReactDOM.render(<MoviePosterContent data={ data } />, $domNode);
<MoviePosterContent><MoviePosterList data={ this.state.pageData }>
<PosterItem data={ pageData[i] }><PosterNameCasts data={ iSrc, iAlt, iTitle, iHref, iCast } /><PosterRatingTheater data={ iRating, itheaterHref } />
</PosterItem></MoviePosterList>
<Navigation data={ this.state.totalPages, this.state.currPageNo } /></MoviePosterContent>
ReactDOM.render( <MoviePosterContent data={ data } />, $domNode );
<MoviePosterContent>
<MoviePosterList data={ this.state.pageData }>
<PosterItem data={ pageData[i] }>
<PosterNameCasts data={ iSrc, iAlt, iTitle, iHref, iCast } />
<PosterRatingTheater data={ iRating, itheaterHref } />
</PosterItem>
</MoviePosterList>
<Navigation data={ this.state.totalPages, this.state.currPageNo } />
</MoviePosterContent>
ReactDOM.render(<MoviePosterContent data={ data } />, $domNode);
<MoviePosterContent><MoviePosterList data={ this.state.pageData }>
<PosterItem data={ pageData[i] }><PosterNameCasts data={ iSrc, iAlt, iTitle, iHref, iCast } /><PosterRatingTheater data={ iRating, itheaterHref } />
</PosterItem></MoviePosterList>
<Navigation data={ this.state.totalPages, this.state.currPageNo } /></MoviePosterContent>
ReactDOM.render( <MoviePosterContent data={ data } />, $domNode );
props = [{
'src' : '/path/to/image','alt' : 'alt text of image','title' : 'name of the movie','href' : '/path/to/the/movie/details/page','cast' : ['array', 'of', 'movie', 'casts'],'rating' : 'movie rating','theater_href' : '/path/to/theater/list'
}, {...}, {...}];
state = {'actualData' : this.props,'currWidth' : 'calculated current screen width','colCount' : 'based on currWidth & max column count','perPage' : 'based on currWidth & colCount','totalPages' : 'based on perPage & actualData length','currPageNo' : 'used in calculating pageData','pageData' : 'based on totalPages & currPageNo'
};
❖ Enter “React Native”, and also - “React Art”, “React Canvas” and “React Three”
❖ Deprecated: “react-tools” package and “JSXTransform.js”
❖ React namespace split into React and ReactDOM
❖ React keep core functionalities for creating components
❖ ReactDOM for rendering in DOM
React.render(<SayMyName name={ myName } />, document.body);
ReactDOM.render(<SayMyName name={ myName } />, document.body);
Flux
Flux Components
• Actions − Actions are sent to dispatcher to trigger the data flow.
• Dispatcher − This is central hub of the app. All the data is dispatched and sent to the stores.
• Store − Store is the place where the application state and logic are held. Every store is maintaining particular state and it will update it when needed.
• View − The view will receive data from the storeand re render the app.
@Webage
Flux Benefits
• Single directional data flow is easy to understand.
• The app is easier to maintain.
• The app parts are decoupled
@Webage
Flux Architecture
• Flux is the application architecture that Facebook uses for building client-side web applications
• . It complements React's composable view components by utilizing a unidirectional data flow.
• Flux applications have three major parts: the dispatcher, the stores, and the views (React components).
@Webage
Flux Architecture
@Webage
Flux flow from view
@Webage
What Happens
• All data flows through the dispatcher as a central hub.• Actions are provided to the dispatcher in an action creator method,
and most often originate from user interactions with the views. • The dispatcher then invokes the callbacks that the stores have
registered with it, dispatching actions to all stores. • Within their registered callbacks, stores respond to whichever
actions are relevant to the state they maintain. • The stores then emit a change event to alert the controller-views
that a change to the data layer has occurred.• Controller-views listen for these events and retrieve data from the
stores in an event handler. • The controller-views call their own setState() method, causing a re-
rendering of themselves and all of their descendants in the component tree.
@Webage
@From Documentation
@Webage
Flux Components and There roles
• A Single Dispatcher :• The dispatcher is the central hub that manages all
data flow in a Flux application. • It is essentially a registry of callbacks into the
stores and has no real intelligence of its own — it is a simple mechanism for distributing the actions to the stores.
• Each store registers itself and provides a callback. When an action creator provides the dispatcher with a new action, all stores in the application receive the action via the callbacks in the registry.
@Webage
Stores
• Stores contain the application state and logic. Their role is somewhat similar to a model in a traditional MVC, but they manage the state of many objects — they do not represent a single record of data like ORM models do.
• Nor are they the same as Backbone's collections. More than simply managing a collection of ORM-style objects, stores manage the application state for a particular domain within the application.
@Webage
Views and Controller-Views
• React provides the kind of composable and freely re-renderable views we need for the view layer.
• Close to the top of the nested view hierarchy, a special kind of view listens for events that are broadcast by the stores that it depends on.
• We call this a controller-view, as it provides the glue code to get the data from the stores and to pass this data down the chain of its descendants.
• We might have one of these controller-views governing any significant section of the page.
@Webage
Actions
• The dispatcher exposes a method that allows us to trigger a dispatch to the stores, and to include a payload of data, which we call an action.
• The action's creation may be wrapped into a semantic helper method which sends the action to the dispatcher.
• This method may be invoked from within our views' event handlers, so we can call it in response to a user interaction.
• This action creator method also adds a type to the action, so that when the action is interpreted in the store, it can respond appropriately.
@Webage
Redux
• Predictable State container (evolution of Flux)
• One single immutable State
• Reducers instead of Stores
• Hot Module Reloading and Time travel Modular, tiny (2kb!)
@Webage
Compared with Flux
@Webage
@Webage
React + Redux
@Webage
ECMAScript2015
const sum = (first, second) => {
return first + second;
}
Created by Sebastian McKenzie
- ECMAScript 2015 Support, JSX Support- Widely adopted
React
React is a JavaScript Library for building user interfaces.
• Focus on the UI, not a Framework
• One-way reactive data flow (no two-way data binding)
• Virtual DOM
Virtual DOM
Keep track of state in DOM is hard.
The DOM API is slow.(Try to re-render the whole DOM on every change)
Virtual DOM
Source: http://teropa.info/blog/2015/03/02/change-and-its-detection-in-javascript-frameworks.html
Virtual DOM
Source: http://teropa.info/blog/2015/03/02/change-and-its-detection-in-javascript-frameworks.html
Virtual DOM Benefits
Batched DOM read/write operations.
Efficient update of sub-tree only.
Our first Experiment Part I
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<script src="bundle.js"></script>
</head>
<body>
<div id="example"></div>
</body>
</html> index.html
Our first Experiment Part II
import React from 'react';
import ReactDOM from 'react-dom';
const exampleElement = document.getElementById
ReactDOM.render(<h1>Hello, world!</h1>, exampleElement
main.js -> bundle.js
JSX
JSX is a JavaScript syntax extensionthat looks similar to XML.
// Input (JSX):
var app = <Nav color="blue" />;
// Output (JS):
var app = React.createElement(Nav, {color
Rendering a Component
import React from 'react';
import ReactDOM from 'react-dom';
const App = () => {
return (<p>Hello World!</p>);
}
const exampleNode = document
.getElementById('example');
ReactDOM.render(<App />, exampleNode);
<body>
<div id="example">
<p> <!-- App start -->
Hello World!
</p> <!-- App end -->
</div>
</body>
index.html
Rendering a Component
Nested Components Part I
import React from 'react';
const Profile = ({avatar, name}) => {
return (
<div>
<img src={avatar} />
<span>{name}</span>
</div>
);
} profile.js
import React from 'react';
import ReactDOM from 'react-dom';
import Profile from ‘./profile';
const App = () => {
return (
<div>
<h1>Hello World!</h1>
<Profile avatar="http://test.png" name="Nik"
</div>
);
}
const exampleNode = document.getElementById('example'
ReactDOM.render(<App />, exampleNode);
main.js -> bundle.js
Nested Components Part II
<body>
<div id="example">
<div> <!-- App start -->
<h1>Hello World!</h1>
<div> <!-- Profile start -->
<img src="http://test.png" />
<span>Nik</span>
</div> <!-- Profile end -->
</div> <!-- App end -->
</div>
</body>index.html
Nested Components Part III
Stateless Function Components
Functional Programming:
- avoid changing-state- avoid mutable data- calling a function twice with the same values as arguments will produce the same result
Stateless Function Components:
- avoid changing-state- avoid mutable data- calling a function twice with the same values as arguments will produce the same result
Wait, but why?
Predictable
easy to understand&easy to test
If/Elseconst Profile = ({name, isOnline}) => {
let onlineIndicator;
if (isOnline) {
onlineIndicator = (<span>green</span>);
} else {
onlineIndicator = (<span>red</span>);
}
return (
<div>
{name} {onlineIndicator}
</div>
);
}
profile.js
If/Else
<Profile name="Nik" isOnline={false}/>
<div>
Nik <span>red</span>
</div>
Loop
const FriendList = ({friends}) => {
return (
<ul>
{friends.map((friend) => {
return <li>{friend.name}</li>;
})}
</ul>
);
}friendlist.js
Loop
const friends = [
{ name: 'Max'},
{ name: 'Tom'},
];
<FriendList friends={friends} />
<ul>
<li>Max</li>
<li>Tom</li>
</ul>
React Summary
- We can create out own components
- We can nest components as we like
- Stateless Function Components are pure
- We can control flow via JS (if, else, for, map …)
Interaction
const Profile = ({name}) => {
return (
<div>
{name}
<button onClick={
console.log('Clicked!'); }>
Click me!
</button>
</div>
);
}profile.js
What to do with interactions likeonMouseOver,
onSubmit &onClick?
Redux to rescue!Redux allows you to manage the state with a minimal API but completely predictablebehaviour.
What about Flux?
Source: https://twitter.com/codecartoons/status/667348216669741056
Basic Principle
(previousState, action) => newState
Redux Flow
StoreActionCreators
ReactComponents
Reducers
Interaction e.g onClick
dispatch(action)
(newState)
(state)
(previousState, action)
Action
const action = {
type: 'ADD_TODO',
text: 'Call Mom',
}
Action Creator
function addTodo(text) {
const trimmedText = text.trim();
return {
type: 'ADD_TODO',
text: trimmedText,
}
}
<button onClick={ dispatch(addTodo('Call Mom ') }
Add Todo
</button>
actions.js
Reducerconst todos = (state = [], action) => {
switch (action.type) {
case 'ADD_TODO':
return [
...state,
{
text: action.text,
completed: false
}
]
default:
return state
}
}
reducers.js
Storeimport { createStore } from 'redux'
import todoReducer from
'../reducers'
let store =
createStore(todoReducer);
store.subscribe(() =>
console.log(store.getState())
)
store.dispatch(addTodo('Learn about
reducers'));
store.dispatch(addTodo(‘Call Mom'));
Connect React with Redux
import React from 'react';
import ReactDOM from 'react-dom';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import todoApp from './reducers';
import App from './containers/App';
let store = createStore(todoApp);
let exampleNode = document.getElementById('example');
ReactDOM.render(
<Provider store={store}><App /></Provider>,
exampleNode
);
Connect React +Redux
import React from 'react';
import { connect } from 'react-redux';
import { addTodo } from '../actions.js';
const App = ({dispatch, state}) => {
return (
<button onClick={ dispatch(addTodo
('Call Mom') }>
Add Todo
</button>
);
};
export default connect(App);
Redux Summary
- Redux allows you to manage the state with predictable behaviour.
- (previousState, action) => newState
Why this Stack?
- Reusable Components
- Predictable Code (functional)
- TimeTravel
- Performant & lightweight
Is it production ready?
React
- used by Facebook, Firefox, Airbnb and many more
Redux
- used by Firefox, Docker, Technical University of Vienna, Mattermark and many more
- “Love what you’re doing with Redux”Jing Chen, creator of Flux
Enzymes
Enzyme is a JavaScript utility library for testing React components.
To install Enzyme, simply run the following commands in your project’s folder:
Why Enzymes
Enzyme’s biggest strength is its shallow rendering capabilities. Not only does this encourage you to limit the scope of your tests to a single component, it also prevents errors deep in your node tree from affecting all your tests, and removes the requirement to mock a ton of objects.
Enzyme gives you a concise and elegant way of simulating user events, one of the trickier aspects of UI testing. Just pass the name of the event you want to simulate, along with any required data
Enzyme is an elegant and powerful way of testing your React applications. It can significantly increase the brevity of your tests thanks to its selector engine, and its approach to event simulation is quite promising.
Shallow Rendering
Shallow rendering is useful to constrain yourself to testing a component as a unit, and to ensure that your tests aren't indirectly asserting on behavior of child components.
Shallow API
Shallow API
End