Runtime type checking for React props and similar
objects.
You can use prop-types to document the intended
types of properties passed to components. React (and potentially other libraries—see the
checkPropTypes() reference below) will check props passed to your components against those
definitions, and warn in development if they don’t match.
Installation
npm install --save
prop-types
Importing
import PropTypes from
'prop-types';
var PropTypes = require('prop-types');
We can create proptypes like this:
State
State
Represents internal state of the component
Accessed via this.state
When a component's state data changes, the rendered markup will be updated by
re-invoking render() method
The virtual DOM is used for efficient re-rendering of the DOM
React aims to re-render the virtual tree only when the state changes
Uses 2 virtual trees (new and previous) to find differences and batch update real
DOM
Observes data changes (setState) and does dirty-checking to know when to re-render
component
Whenever possible, does not update entire component in real DOM - only computes a
patch operation that updates part of the DOM
Examples
A simple component
A simple component
* see live example *
A nested component
A nested component
* see live example *
A stateful component
A stateful component
* see live example *
An app
An app
Hello World
import React from 'react';
import ReactDOM from 'react-dom';
ReactDOM.render(
<h1>Hello, world!</h1>
document.getElementById('title')
);
Introduction to JSX
JSX is a statically-typed, object-oriented programming
language compiling to standalone JavaScript.
The first thing you'll notice is the XML-ish syntax in
your JavaScript.
React without JSX
class SubjectList extends React.Component {
render() {
return
React.createElement('div', {className: ‘subject-list'},
React.createElement('h2', {}, ‘Subjects List for {this.props.name}’),
React.createElement('ul', {},
React.createElement(‘li', {}, "Math") ,
React.createElement(‘li', {}, "English") ,
React.createElement(‘li', {}, "Javascript")
);
);
}
}
// Example usage: <SubjectList name=“Miley" />
React with JSX
class SubjectList extends React.Component {
render() {
return (
<div className=‘subject-list’>
<h2>Subjects List for {this.props.name}</h2>
<ul>
<li>Math</li>
<li>English</li>
<li>JavaScript</li>
</ul>
</div>
);
}
}
// Example usage: < SubjectList name=“Miley" />
Life cycle
ReactElement
This is the primary type in React.
Light, stateless,
immutable, virtual representation of a DOM Element.
Lives in the virtual DOM
Their immutability makes
them easy and fast to compare and update. This is the reason of great React performance.
ReactElement
They are stateless, therefore
don’t seem to be very helpful for the programmers
JSX
compiles HTML tags to ReactElements:
var root = <div>hello world</div>;
ReactDOM.render(root,document.getElementById('example'));.
ReactComponent
What differs ReactComponent from ReactElement is -
ReactComponents are stateful.
var CommentBox = React.createClass({
render: function() {
return (
<div className="commentBox">
Hello, world! I am a CommentBox.
</div>
);
}
});
Event Handling and Synthetic Events
With React you simply pass your event handler as a
camelCased prop
React ensures that all events behave similarly in all
browsers
by implementing a
synthetic event system
Under the Hood
Autobinding
Event Delegation
Autobinding
When creating callbacks in JavaScript, you usually need
to explicitly bind a method to its instance such that the value of 'this' is correct.
var person = {firstName: ‘Black', lastName: ‘Mark'};
function say() {
console.log('Hello ' + this.firstName + ' ' + this.lastName);
}
var sayHello = say.bind(person);
sayHello(); // Hello Black Mark
Event Delegation
React doesn't actually attach event handlers to the
nodes themselves.
When React starts up
It starts listening
for all events at the top level using a single event listener.
When a component is mounted or unmounted
the event handlers are
simply added or removed from an internal mapping
When an event occurs, React knows how to dispatch it
using this mapping
Separation of Concerns
By building modular components that reuse other
components with well-defined interfaces
you get much of the same
benefits that you get by using functions or classes
This is bad because it
leads to paralysis and confusion.
Inline styles avoid this, because the CSS is scoped to
the component.
Component CSS
var Title = React.createClass({
titleText: "Some text",
render(){
var inlineCss = {
padding:'10px',
lineHeight:'16px',
color:'red'
}
return<div>
<h1 style={inlineCss}>{titleText}</h1>
</div>
}
})
Not really inline
Style is actually a much better name than class.
You want to “style”
the element, not “class” it.
Finally, this is not applying the style directly, this
is using React virtual DOM and is being diff-ed the same way elements are.
<h1 style={inlineCss}>{titleText}</h1>
Conditional Rendering
Conditional rendering in React works the same way
conditions work in JavaScript.
Use JavaScript operators like
if or the conditional operator to create elements
representing the current state, and let React update the UI to match them.
var Greeting = React.createClass({
const isLoggedIn = this.props.isLoggedIn;
if (isLoggedIn) { return <UserGreeting />; }
return <GuestGreeting />;
});
The Dispatcher is basically the manager of entire
process.
Receives actions and dispatches the actions and data to
registered callbacks
Dispatcher
One
dispatcher per application
import { Dispatcher } from 'flux';
export default new Dispatcher;
ActionCreators & Actions
Action Creators are collections of methods that are
called within views to send actions to the Dispatcher.
Actions are the actual payloads that are delivered via
the dispatcher.
import dispatcher from '../dispatcher';
export function createTodo(text, competed){
dispatcher.dispatch({type:"CREATE_TODO", text: text, complete:completed});
}
export function deleteTodo(id){
dispatcher.dispatch({type:"DELETE_TODO", id: id});
}
Stores
Stores manage application state for a particular domain
within your application.
This basically means that per app section Stores manage
The data
Data retrieval methods
Dispatcher callbacks
Stores
import EventEmitter from 'events';
import dispatcher from '../dispatcher';
class TodoStore extends EventEmitter{
constructor(){
super();
this.todos = [...]
}
getAllTodos(){
return this.todos;
}
createTod(text, completed){
let id=Date.now();
this.todos.push({id: id, text, complete: completed});
// this.emit("change");
}
updateTodo(){
// this.emit("update");
}
handleAction(action){
console.log(action);
switch(acction.type){
case 'CREATE_TODO': this>createTodo(action.text, action.complete);
break;
}
}
}
var todoStore = new TodoStore;
dispatcher.register(todoStore.handleAction.bind(todoStore));
Stores
The most important thing we did above is to extend our
store with NodeJS’s EventEmitter.
Allows our stores to
listen/broadcast events.
Allows our
Views/Components to update based upon those events
Because our Controller
View listens to our Stores, leveraging this to emit change events will let our
Controller View know that our application state has changed and its time to retrieve the
state to keep things fresh.
Stores
We also registered a callback with our Dispatcher using
its register method.
This means that our Store
is now listening to Dispatcher broadcasts.
Our switch statement
determines if there are any relevant actions to take.
If a relevant action is
taken, a change event is emitted, and views that are listening for this event update their
states.
Stores
Controller Views
Controller views are really
just React components
That listen to change events and retrieve
Application state from Stores.
Our switch statement determines if there are any
relevant actions to take.
They then pass that data down to their child
components via props.
Controller Views
import React from 'react';
import Todo from '../components/Todo';
import todoStore from '../store/TodoStore';
import * as TodoAction from '../action/TodoAction';
export default class Todos extends React.Component {
constructor(){
super();
this.state = {
todo: todoStore.getAllTodos()
};
}
componentWillMount(){
todoStore.on("change", ()=>{
let todos = todoStore.gerAllTodos();
this.setState({todos: todos});
});
todoStore.on("update", ()=>{
console.log("update date...");
});
}
createTodo(){
let text = "Read Java";
let complete = false;
TodoAction.createTodo(text, complete);
}
}
Redux is a pattern and library for managing and
updating application state, using events called "actions".
Understand when, where, why, and how the state in your
application is being updated
How your application logic will behave when those
changes occur
React Key Concepts
Store:
A store is a state container which holds
the
application’s state. Redux can have only a single store in your application. Whenever a
store is
created in Redux, you need to specify the reducer.
Reducers:
The Reducer function in the redux helps
us
to return the new app state by taking the previous app state and type of action.
The following few things should never be performed
inside the reducer −
Mutation of functions arguments
API calls & routing logic
Calling non-pure function e.g. Math.random()
Container:
The container is the function (usually
in
a separate
file) which gives the component props the special ability to interact with state.
Actions:
Actions are the only source of
information for the store. Actions have a type field that
tells what kind of action to perform and all other fields contain information or data.
Providers:
The Provide component makes the Redux store available to any nested components that
need to access the Redux store.
When Should I Use Redux?
You have large amounts of application state that are
needed in many places in the app
The app state is updated frequently over time
The logic to update that state may be complex
The app has a medium or large-sized codebase, and might
be worked on by many people
Core Concepts
The state, the source of truth that drives our app;
The view, a declarative description of the UI based
on the current state
The actions, the events that occur in the app based
on user input, and trigger updates in the state
Redux Data Flow
Store
One single store for entire application
Store are created using createStore method
syntax: redux.createStore(reducer)
Reducers
Modify the state depending on action
Don't directly modify the state
No side effects (http calls not allowed)
Dispatch
Dispatches actions to store, reaches reducer
then
The only way to update the state is to call
store.dispatch() and pass in an action object.
Redux MiddleWare
Middleware
Enhancers are powerful because they can override or
replace any of the store's methods: dispatch, getState,
and subscribe.
But, much of the time, we only need to customize
how
dispatch behaves. It would be nice if there was a way to add some
customized behavior when dispatch runs.
Redux uses a special kind of addon called
middleware to let us customize the dispatch function.
Implementing Middleware
Redux middleware are actually implemented on top of
a very special store enhancer that comes built in with Redux, called
applyMiddleware.
We'll start with applyMiddleware by itself, and
we'll add three example middleware
Unlike a reducer,
middleware can have side effects inside, including timeouts
and other async logic.
Writing Custom Middleware
We can write our own middleware. You might not
need to do this all the time, but custom middleware are a great way to add specific
behaviors to a Redux application.
Redux middleware are written as a series of
three nested functions
Because these are normal functions, we can also
write them using ES6 arrow functions. This lets us write them shorter because arrow
functions don't have to have a return statement, but it can also be a bit harder to read if
you're not yet familiar with arrow functions and implicit returns.
Here's the same example as above, using arrow
functions:
Redux Thunk
Thunk Middleware
Redux already has an official version of that "async function middleware",
called the Redux "Thunk" middleware. The thunk middleware allows us to
write functions that
get dispatch and getState as arguments. The thunk
functions can have any async logic we want
inside, and that logic can dispatch actions and read the store state as needed.
Writing async logic as thunk functions
allows us to reuse that logic without
knowing what Redux store we're using ahead of time.
Configuring the Store
The Redux thunk middleware is available on NPM as a package called
redux-thunk. We need to
install that package to use it in our app:
Once it's installed, we can update the Redux store
Or if you want to add a design component in our
React application, we can use Redux Thunk to set up middleware. To do this, we have modified
the above code by including the HTML and CSS components as shown
RxJS
RxJS
RxJS is a JavaScript library that uses observables to work with reactive programming that
deals with asynchronous data calls, callbacks and event-based programs.
Features of RxJS:
Observable :An observable is a function that creates an
observer and attaches it to the source
where values are expected, for example, clicks, mouse events from a dom element
or
an Http request, etc.
Observer :It is an object with next(), error() and complete()
methods, that will get called
when there is interaction to the with the observable i.e. the source interacts
for
an example button click, Http request, etc.
Subscription : A subject is an observable that can multicast
i.e. talk to many observers. Consider
a button with an event listener, the function attached to the event using
addlistener is called every time the user clicks on the button similar
functionality
goes for subject too.
Operators : An operator is a pure function that
takes
in observable as input and the output is
also an observable.
Features of RxJS:
Subject :A subject is an observable that can multicast i.e.
talk to
many observers. Consider a button
with an event listener, the function attached to the event using addlistener is
called
every
time the user clicks on the button similar functionality goes for subject too.
Schedulers :A scheduler controls the execution of when the
subscription
has to start and
notified.
Best Practices
Always define your propTypes.
For any propType that isn't required, always set it in getDefaultProps.
Rely on ...spreadSyntax over passing props explicity.
Place your derived props or state in render() rather than in getInitialState().
Use
JSX
ES6 (transpiled with Babel)
Webpack
Best Practices
Always look at your bundle size
Bad=>import {Foo} from ‘foo’ Good=>import Foo from ‘foo/Foo’
Keep your components small (Very Small)
Minimize your States
Avoid synchronizing state between a child and
parent
Use ShouldComponentUpdate for performance optimization