React Part2
React Part2
React is a declarative, component-based JavaScript library used for creating user interfaces.
To achieve MVC framework like functionalities in React, developers use it in conjunction with a
Flux flavour of choice, e.g. Redux.
Versions
0.3.0 2013-05-29
0.4.0 2013-07-17
0.5.0 2013-10-16
0.8.0 2013-12-19
0.9.0 2014-02-20
0.10.0 2014-03-21
0.11.0 2014-07-17
0.12.0 2014-10-28
0.13.0 2015-03-10
0.14.0 2015-10-07
15.0.0 2016-04-07
15.1.0 2016-05-20
15.2.0 2016-07-01
15.2.1 2016-07-08
15.3.0 2016-07-29
15.3.1 2016-08-19
15.3.2 2016-09-19
15.4.0 2016-11-16
http://java2aspire.com/ 1
Version Release Date
15.4.1 2016-11-23
15.4.2 2017-01-06
15.5.0 2017-04-07
15.6.0 2017-06-13
16.0 2017-09-13
16.1 2018-01-13
16.3.0 2018-03-29
16.4.0 2018-05-01
16.5.0 2018-09-07
16.8.0 2019-02-13
16.10.0 2019-09-27
16.12.0 2019-11-14
Installation or Setup
ReactJS is a JavaScript library contained in a single file react-<version>.js that can be included in
any HTML page. People also commonly install the React DOM library react-dom-<version>.js
along with the main React file:
Basic Inclusion
<!DOCTYPE html>
<html>
<head></head>
<body>
<script type="text/javascript" src="/path/to/react.js"></script>
<script type="text/javascript" src="/path/to/react-dom.js"></script>
<script type="text/javascript">
// Use react JavaScript code here or in a separate file
</script>
</body>
</html>
To get the JavaScript files, go to the installation page of the official React documentation.
React also supports JSX syntax. JSX is an extension created by Facebook that adds XML syntax
to JavaScript. In order to use JSX you need to include the Babel library and change <script
type="text/javascript"> to <script type="text/babel"> in order to translate JSX to Javascript code.
http://java2aspire.com/ 2
<!DOCTYPE html>
<html>
<head></head>
<body>
<script type="text/javascript" src="/path/to/react.js"></script>
<script type="text/javascript" src="/path/to/react-dom.js"></script>
<script src="https://npmcdn.com/babel-core@5.8.38/browser.min.js"></script>
<script type="text/babel">
// Use react JSX code here or in a separate file
</script>
</body>
</html>
http://java2aspire.com/ 3
You can also install React using npm by doing the following:
Facebook released its own package manager named Yarn, which can also be used to install
React. After installing Yarn you just need to run this command:
You can then use React in your project in exactly the same way as if you had installed React via
npm.
A React component can be defined as an ES6 class that extends the base React.Component class.
In its minimal form, a component must define a render method that specifies how the component
renders to the DOM. The render method returns React nodes, which can be defined using JSX
syntax as HTML-like tags. The following example shows how to define a minimal Component:
A Component can also receive props. These are properties passed by its parent in order to specify
some values the component cannot know by itself; a property can also contain a function that can
be called by the component after certain events occur - for example, a button could receive a
function for its onClick property and call it whenever it is clicked. When writing a component, its
props can be accessed through the props object on the Component itself:
http://java2aspire.com/ 4
The example above shows how the component can render an arbitrary string passed into the name
prop by its parent. Note that a component cannot modify the props it receives.
A component can be rendered within any other component, or directly into the DOM if it's the
topmost component, using ReactDOM.render and providing it with both the component and the DOM
Node where you want the React tree to be rendered:
By now you know how to make a basic component and accept props. Lets take this a step further
and introduce state.
For demo sake, let's make our Hello World app, display only the first name if a full name is given.
constructor(props){
render() {
return <h1>Hello, {this.state.name}!</h1>
}
}
Note: Each component can have it's own state or accept it's parent's state as a prop.
Hello World
Without JSX
http://java2aspire.com/ 5
Here's a basic example that uses React's main API to create a React element and the React DOM
API to render the React element in the browser.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello React!</title>
</head>
<body>
<div id="example"></div>
<script type="text/javascript">
</script>
</body>
</html>
With JSX
Instead of creating a React element from strings one can use JSX (a Javascript extension created
by Facebook for adding XML syntax to JavaScript), which allows to write
as the equivalent (and easier to read for someone familiar with HTML)
The code containing JSX needs to be enclosed in a <script type="text/babel"> tag. Everything
within this tag will be transformed to plain Javascript using the Babel library (that needs to be
included in addition to the React libraries).
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello React!</title>
http://java2aspire.com/ 6
<!-- Include the React and ReactDOM libraries -->
<script src="https://fb.me/react-15.2.1.js"></script>
<script src="https://fb.me/react-dom-15.2.1.js"></script>
<!-- Include the Babel library -->
<script src="https://npmcdn.com/babel-core@5.8.38/browser.min.js"></script>
</head>
<body>
<div id="example"></div>
<script type="text/babel">
</script>
</body>
</html>
What is ReactJS?
ReactJS is an open-source, component based front end library responsible only for the view layer
of the application. It is maintained by Facebook.
ReactJS uses virtual DOM based mechanism to fill in data (views) in HTML DOM. The virtual
DOM works fast owning to the fact that it only changes individual DOM elements instead of
reloading complete DOM every time
React allows us to write components using a domain-specific language called JSX. JSX allows us
to write our components using HTML, whilst mixing in JavaScript events. React will internally
convert this into a virtual DOM, and will ultimately output our HTML for us.
React "reacts" to state changes in your components quickly and automatically to rerender the
components in the HTML DOM by utilizing the virtual DOM. The virtual DOM is an in-memory
representation of an actual DOM. By doing most of the processing inside the virtual DOM rather
than directly in the browser's DOM, React can act quickly and only add, update, and remove
components which have changed since the last render cycle occurred.
http://java2aspire.com/ 7
Stateless components are getting their philosophy from functional programming. Which implies
that: A function returns all time the same thing exactly on what is given to it.
For example:
let a = 0;
const statefulSum = () => a++;
As you can see from the above example that, statelessSum is always will return the same values
given a and b. However, statefulSum function will not return the same values given even no
parameters. This type of function's behaviour is also called as a side-effect. Since, the component
affects somethings beyond.
So, it is advised to use stateless components more often, since they are side-effect free and will
create the same behaviour always. That is what you want to be after in your apps because
fluctuating state is the worst case scenario for a maintainable program.
The most basic type of react component is one without state. React components that are pure
functions of their props and do not require any internal state management can be written as simple
JavaScript functions. These are said to be Stateless Functional Components because they are a
function only of props, without having any state to keep track of.
// In HTML
<div id="element"></div>
// In React
const MyComponent = props => {
return <h1>Hello, {props.name}!</h1>;
};
Note that all that this component does is render an h1 element containing the name prop. This
component doesn't keep track of any state. Here's an ES6 example as well:
HelloWorld.propTypes = {
name: React.PropTypes.string.isRequired
}
http://java2aspire.com/ 8
Since these components do not require a backing instance to manage the state, React has more
room for optimizations. The implementation is clean, but as of yet no such optimizations for
stateless components have been implemented.
Installation
First, install create-react-app globally with node package manager (npm).
create-react-app my-app
Navigate to the newly created directory and run the start script.
cd my-app/
npm start
Configuration
create-react-app is intentionally non-configurable by default. If non-default usage is required, for
example, to use a compiled CSS language such as Sass, then the eject command can be used.
This allows editing of all configuration files. N.B. this is an irreversible process.
Alternatives
Alternative React boilerplates include:
• enclave
• nwb
http://java2aspire.com/ 9
• motion
• rackt-cli
• budō
• rwb
• quik
• sagui
• roc
It can be useful to think of React components as simple functions - they take input in the form of
"props", and produce output as markup. Many simple components take this a step further, making
themselves "Pure Functions", meaning they do not issue side effects, and are idempotent (given a
set of inputs, the component will always produce the same output). This goal can be formally
enforced by actually creating components as functions, rather than "classes". There are three
ways of creating a React component:
• React.createClass()
http://java2aspire.com/ 10
• ES2015 Classes
Functional components cannot have "state" within them. So if your component needs to have a
state, then go for class based components.
As a final note, react props are immutable once they have been passed in, meaning they cannot
be modified from within a component. If the parent of a component changes the value of a prop,
React handles replacing the old props with the new, the component will rerender itself using the
new values.
See Thinking In React and Reusable Components for deeper dives into the relationship of props
to components.
http://java2aspire.com/ 11
Communicate Between Components
Communication between Stateless Functional Components
In this example we will make use of Redux and React Redux modules to handle our application state
and for auto re-render of our functional components., And ofcourse React and React Dom
In the example below we have three different components and one connected component
• UserInputForm: This component display an input field And when the field value changes, it
calls inputChange method on props (which is provided by the parent component) and if the
data is provided as well, it displays that in the input field.
• UserDashboard: This component displays a simple message and also nests UserInputForm
component, It also passes inputChange method to UserInputForm component, UserInputForm
component inturn makes use of this method to communicate with the parent component.
return(
<form action="" onSubmit={handleSubmit}>
<label htmlFor="name">Please enter your name</label>
<br />
<input type="text" id="name" defaultValue={props.data.name || ''} onChange={
props.inputChange } />
</form>
)
http://java2aspire.com/ 12
}
return(
<div>
<h1>Hi { props.user.name || 'User' }</h1>
<UserInputForm data={props.user} inputChange={inputChangeHandler} />
</div>
)
default:
return state;
}
};
ReactDOM.render(
http://java2aspire.com/ 13
<Provider store={ store }>
<App />
</Provider>,
document.getElementById('application')
);
http://java2aspire.com/ 14
Communication Between Components
Remarks
There are a total of 3 cases of communication between React components:
Examples
Parent to Child Components
That the easiest case actually, very natural in the React world and the chances are - you are
already using it.
You can pass props down to child components. In this example message is the prop that we
pass down to the child component, the name message is chosen arbitrarily, you can name it
anything you want.
Here, the <Parent /> component renders two <Child /> components, passing message for child
inside the first component and 5 inside the second one.
In summary, you have a component (parent) that renders another one (child) and passes to it
some props.
http://java2aspire.com/ 15
Child to Parent Components
Sending data back to the parent, to do this we simply pass a function as a prop from the parent
component to the child component, and the child component calls that function.
In this example, we will change the Parent state by passing a function to the Child component and
invoking that function inside the Child component.
this.outputEvent = this.outputEvent.bind(this);
}
outputEvent(event) {
// the event context comes from the Child
this.setState({ count: this.state.count++ });
}
render() {
const variable = 5;
return (
<div>
Count: { this.state.count }
<Child clickHandler={this.outputEvent} />
</div>
);
}
}
Note that the Parent's outputEvent method (that changes the Parent state) is invoked by the Child's
button onClick event.
Not-related Components
The only way if your components does not have a parent-child relationship (or are related but too
further such as a grand grand grand son) is to have some kind of a signal that one component
subscribes to, and the other writes into.
Those are the 2 basic operations of any event system: subscribe/listen to an event to be notify,
http://java2aspire.com/ 16
and send/trigger/publish/dispatch a event to notify the ones who wants.
• Pattern 2: Publish/Subscribe: you don't need a specific reference to the source that triggers
the event, there is a global object accessible everywhere that handles all the events.
• Pattern 3: Signals: similar to Event Emitter/Target/Dispatcher but you don't use any random
strings here. Each object that could emit events needs to have a specific property with that
name. This way, you know exactly what events can an object emit.
Components
Remarks
was deprecated in v15.5 and expected to be removed in v16. There is a drop-in
React.createClass
replacement package for those that still require it. Examples using it should be updated.
Examples
Basic Component
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>React Tutorial</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.2.1/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.2.1/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-
core/5.8.34/browser.min.js"></script>
</head>
<body>
<div id="content"></div>
<script type="text/babel" src="scripts/example.js"></script>
</body>
</html>
http://java2aspire.com/ 17
You can create a basic component using the following code in a separate file:
scripts/example.js
http://java2aspire.com/ 18
You will get the following result (note what is inside of div#content):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>React Tutorial</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.2.1/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.2.1/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-
core/5.8.34/browser.min.js"></script>
</head>
<body>
<div id="content">
<div className="firstComponent">
Hello, world! I am a FirstComponent.
</div>
</div>
<script type="text/babel" src="scripts/example.js"></script>
</body>
</html>
Nesting Components
A lot of the power of ReactJS is its ability to allow nesting of components. Take the following two
components:
You can nest and refer to those components in the definition of a different component:
http://java2aspire.com/ 19
return (
<div className="commentBox">
<h1>Comments</h1>
<CommentList /> // Which was defined above and can be reused
<CommentForm /> // Same here
</div>
);
}
});
Further nesting can be done in three ways, which all have their own places to be used.
Pros
• Easy and fast to separate UI elements
• Easy to inject props down to children based on the parent component's state
Cons
• Less visibility into the composition architecture
• Less reusability
Good if
• B and C are just presentational components
• B should be responsible for C's lifecycle
http://java2aspire.com/ 20
var CommentBox = reactCreateClass({
render: function() {
return (
<div className="commentBox">
<h1>Comments</h1>
<CommentList>
<ListTitle/> // child
</CommentList>
<CommentForm />
</div>
);
}
});
This is the style where A composes B and A tells B to compose C. More power to parent
components.
Pros
• Better components lifecycle management
• Better visibility into the composition architecture
• Better reusuability
Cons
• Injecting props can become a little expensive
• Less flexibility and power in child components
Good if
• B should accept to compose something different than C in the future or somewhere else
• A should control the lifecycle of C
B would render C using this.props.children, and there isn't a structured way for B to know what
those children are for. So, B may enrich the child components by giving additional props down, but
if B needs to know exactly what they are, #3 might be a better option.
http://java2aspire.com/ 21
);
}
});
This is the style where A composes B and B provides an option for A to pass something to
compose for a specific purpose. More structured composition.
Pros
• Composition as a feature
• Easy validation
• Better composaiblility
Cons
• Injecting props can become a little expensive
• Less flexibility and power in child components
Good if
• B has specific features defined to compose something
• B should only know how to render not what to render
#3 is usually a must for making a public library of components but also a good practice in general
to make composable components and clearly define the composition features. #1 is the easiest
and fastest to make something that works, but #2 and #3 should provide certain benefits in various
use cases.
Creating Components
render(
http://java2aspire.com/ 22
<FirstComponent name={ 'User' } />,
document.getElementById('content')
);
In such a case, some people find it preferable to use Stateless Functional Components, which are
based on ES6 arrow functions.
1. When rendered they receive an object with all the props that were passed down
2. They must return the JSX to be rendered
Stateful Components
In contrast to the 'stateless' components shown above, 'stateful' components have a state object
that can be updated with the setState method. The state must be initialized in the constructor
before it can be set:
http://java2aspire.com/ 23
this.state = {
toggle: true
};
onClick() {
this.setState((prevState, props) => ({
toggle: !prevState.toggle
}));
}
render() {
return (
<div onClick={this.onClick}>
Hello, {this.props.name}! I am a SecondComponent.
<br />
Toggle is: {this.state.toggle}
</div>
);
}
}
Extending a component with PureComponent instead of Component will automatically implement the
shouldComponentUpdate() lifecycle method with shallow prop and state comparison. This keeps your
application more performant by reducing the amount of un-necessary renders that occur. This
assumes your components are 'Pure' and always render the same output with the same state and
props input.
http://java2aspire.com/ 24
const ExtendedComponent = PrintHello(FirstComponent);
Higher order components are used when you want to share logic across several components
regardless of how different they render.
setState pitfalls
You should use caution when using setState in an asynchronous context. For example, you might
try to call setState in the callback of a get request:
this.state = {
user: {}
};
}
componentDidMount() {
this.fetchUser();
}
fetchUser() {
$.get('/api/users/self')
.then((user) => {
this.setState({user: user});
});
}
render() {
return <h1>{this.state.user}</h1>;
}
}
This could call problems - if the callback is called after the Component is dismounted, then
this.setState won't be a function. Whenever this is the case, you should be careful to ensure your
usage of setState is cancellable.
In this example, you might wish to cancel the XHR request when the component dismounts:
this.state = {
user: {},
xhr: null
};
}
componentWillUnmount() {
let xhr = this.state.xhr;
http://java2aspire.com/ 25
xhr.abort();
}
}
componentDidMount() {
this.fetchUser();
}
fetchUser() {
let xhr = $.get('/api/users/self')
.then((user) => {
this.setState({user: user});
});
this.setState({xhr: xhr});
}
}
The async method is saved as a state. In the componentWillUnmount you perform all your cleanup -
including canceling the XHR request.
You could also do something more complex. In this example, I'm creating a 'stateSetter' function
that accepts the this object as an argument and prevents this.setState when the function cancel
has been called:
function stateSetter(context) {
var cancelled = false;
return {
cancel: function () {
cancelled = true;
},
setState(newState) {
if (!cancelled) {
context.setState(newState);
}
}
}
}
http://java2aspire.com/ 26
render() {
return <h1>{this.state.user}</h1>
}
}
This works because the cancelled variable is visible in the setState closure we created.
Props
Props are a way to pass information into a React component, they can have any type including
functions - sometimes referred to as callbacks.
Inside the definition for MyComponent userID will now be accessible from the props object
It's important to define all props, their types, and where applicable, their default value:
MyComponent.defaultProps = {
someObject: {},
title: 'My Default Title'
}
In this example the prop someObject is optional, but the prop userID is required. If you fail to provide
userID to MyComponent, at runtime the React engine will show a console warning you that the
required prop was not provided. Beware though, this warning is only shown in the development
version of the React library, the production version will not log any warnings.
to
http://java2aspire.com/ 27
console.log(this.props.title);
It's also a safeguard for use of object array and functions. If you do not provide a default prop for
an object, the following will throw an error if the prop is not passed:
if (this.props.someObject.someKey)
In example above, this.props.someObject is undefined and therefore the check of someKey will throw
an error and the code will break. With the use of defaultProps you can safely use the above check.
Suppose we want to have the following behaviour - We have a heading (say h3 element) and on
clicking it, we want it to become an input box so that we can modify heading name. React makes
this highly simple and intuitive using component states and if else statements. (Code explanation
below)
// I have used ReactBootstrap elements. But the code works with regular html elements also
var Button = ReactBootstrap.Button;
var Form = ReactBootstrap.Form;
var FormGroup = ReactBootstrap.FormGroup;
var FormControl = ReactBootstrap.FormControl;
handleTitleSubmit: function() {
//code to handle input box submit - for example, issue an ajax request to change name in
database
},
handleTitleChange: function(e) {
//code to change the name in form input box. newTitle is initialized as empty string. We
need to update it with the string currently entered by user in the form
this.setState({newTitle: e.target.value});
},
changeComponent: function() {
// this toggles the show variable which is used for dynamic UI
this.setState({show: !this.state.show)};
},
render: function() {
var clickableTitle;
if(this.state.show) {
clickableTitle = <Form inline onSubmit={this.handleTitleSubmit}>
<FormGroup controlId="formInlineTitle">
<FormControl type="text" onChange={this.handleTitleChange}>
</FormGroup>
</Form>;
} else {
clickabletitle = <div>
http://java2aspire.com/ 28
<Button bsStyle="link" onClick={this.changeComponent}>
<h3> Default Text </h3>
</Button>
</div>;
}
return (
<div className="comment">
{clickableTitle}
</div>
);
}
});
ReactDOM.render(
<Comment />, document.getElementById('content')
);
The main part of the code is the clickableTitle variable. Based on the state variable show, it can
be either be a Form element or a Button element. React allows nesting of components.
So we can add a {clickableTitle} element in the render function. It looks for the clickableTitle
variable. Based on the value 'this.state.show', it displays the corresponding element.
const languages = [
'JavaScript',
'Python',
'Java',
'Elm',
'TypeScript',
'C#',
'F#'
]
// one liner
const Language = ({language}) => <li>{language}</li>
Language.propTypes = {
message: React.PropTypes.string.isRequired
}
/**
* If there are more than one line.
* Please notice that round brackets are optional here,
* However it's better to use them for readability
*/
const LanguagesList = ({languages}) => {
<ul>
{languages.map(language => <Language language={language} />)}
</ul>
}
LanguagesList.PropTypes = {
http://java2aspire.com/ 29
languages: React.PropTypes.array.isRequired
}
/**
* This syntax is used if there are more work beside just JSX presentation
* For instance some data manipulations needs to be done.
* Please notice that round brackets after return are required,
* Otherwise return will return nothing (undefined)
*/
const LanguageSection = ({header, languages}) => {
// do some work
const formattedLanguages = languages.map(language => language.toUpperCase())
return (
<fieldset>
<legend>{header}</legend>
<LanguagesList languages={formattedLanguages} />
</fieldset>
)
}
LanguageSection.PropTypes = {
header: React.PropTypes.string.isRequired,
languages: React.PropTypes.array.isRequired
}
ReactDOM.render(
<LanguageSection
header="Languages"
languages={languages} />,
document.getElementById('app')
)
Controlled form components are defined with a value property. The value of controlled inputs is
managed by React, user inputs will not have any direct influence on the rendered input. Instead, a
change to the value property needs to reflect this change.
http://java2aspire.com/ 30
class Form extends React.Component {
constructor(props) {
super(props);
this.onChange = this.onChange.bind(this);
this.state = {
name: ''
};
}
onChange(e) {
this.setState({
name: e.target.value
});
}
render() {
return (
<div>
<label for='name-input'>Name: </label>
<input
id='name-input'
onChange={this.onChange}
value={this.state.name} />
</div>
)
}
}
The above example demonstrates how the value property defines the current value of the input
and the onChange event handler updates the component's state with the user's input.
Form inputs should be defined as controlled components where possible. This ensures that the
component state and the input value is in sync at all times, even if the value is changed by a
trigger other than a user input.
Uncontrolled Components
Uncontrolled components are inputs that do not have a value property. In opposite to controlled
components, it is the application's responsibility to keep the component state and the input value
in sync.
http://java2aspire.com/ 31
class Form extends React.Component {
constructor(props) {
super(props);
this.onChange = this.onChange.bind(this);
this.state = {
name: 'John'
};
}
onChange(e) {
this.setState({
name: e.target.value
});
}
render() {
return (
<div>
<label for='name-input'>Name: </label>
<input
id='name-input'
onChange={this.onChange}
defaultValue={this.state.name} />
</div>
)
}
}
Here, the component's state is updated via the onChange event handler, just as for controlled
components. However, instead of a value property, a defaultValue property is supplied. This
determines the initial value of the input during the first render. Any subsequent changes to the
component's state are not automatically reflected by the input value; If this is required, a controlled
component should be used instead.
http://java2aspire.com/ 32
Higher Order Components
Introduction
Higher Order Components ("HOC" in short) is a react application design pattern that is used to
enhance components with reusable code. They enable to add functionality and behaviors to
existing component classes.
A HOC is a pure javascript function that accepts a component as it's argument and returns a new
component with the extended functionality.
Remarks
HOCs are pretty often used in third party libraries. Such as the Redux connect function.
Examples
Simple Higher Order Component
hocLogger.js
MyLoggedComponent.js
http://java2aspire.com/ 33
}
Let's say we have a component that should only be displayed if the user is logged in.
AuthenticatedComponent.js
/**
* Check if the user is authenticated, this.props.isAuthenticated
* has to be set from your application logic (or use react-redux to retrieve it from
global state).
*/
isAuthenticated() {
return this.props.isAuthenticated;
}
/**
* Render
*/
render() {
const loginErrorMessage = (
<div>
Please <a href="/login">login</a> in order to view this part of the
application.
</div>
);
return (
<div>
{ this.isAuthenticated === true ? <Component {...this.props} /> :
loginErrorMessage }
</div>
);
}
};
}
We then just use this Higher Order Component in our components that should be hidden from
anonymous users:
MyPrivateComponent.js
http://java2aspire.com/ 34
import {requireAuthentication} from "./AuthenticatedComponent";
http://java2aspire.com/ 35
How and why to use keys in React
Introduction
Whenever you are rendering a list of React components, each component needs to have a key
attribute. The key can be any value, but it does need to be unique to that list.
When React has to render changes on a list of items, React just iterates over both lists of children
at the same time and generates a mutation whenever there's a difference. If there are no keys set
for the children, React scans each child. Otherwise, React compares the keys to know which were
added or removed from the list
Remarks
For more information, visit this link to read how to use keys:
https://facebook.github.io/react/docs/lists-and-keys.html
Examples
Basic Example
function SomeComponent(props){
return (
<ul>
{getItemsList()}
</ul>
);
}
<ul>
<li key='cat'>cat</li>
<li key='dog'>dog</li>
<li key='rat'>rat</li>
<ul>
http://java2aspire.com/ 36
How to setup a basic webpack, react and
babel environment
Remarks
This build pipeline is not exactly what you would call "production ready" but it does give a solid
start for you to add on to it the things that you need in order to get the development experience
you're looking for. The approach that some people take (including myself at times) is to take a fully
built up pipeline of Yeoman.io or somewhere else and then strip off the things they don't want until
it suits there style. There's nothing wrong with this but perhaps with the example above you could
opt for the opposite approach and build up from bare bones.
Some things you might like to add are things like a testing framework and coverage statistics like
Karma with Mocha or Jasmine. Linting with ESLint. Hot module replacement in webpack-dev-
server so that you can get that Ctrl+S, F5 development experience. Also the current pipeline only
builds in dev mode so a production build task would be good.
Gotchas!
Notice in the context property of the webpack.config.js we have used the node path module to
define our path rather than just concatenating dirname to the string /src this is because windows
hates forward slashses. So to make the solution more cross platform compatible use leverage
node to help us.
context
This is the filepath for which webpack will use as it's root path for the purposes of resolving relative
file paths. So in index.jsx where we use require('./index.html') that dot actually resolves to the
src/ directory because we've defined it as such in this property.
entry
Where webpack looks first to begin bundling the solution. This is why you'll see that in the
index.jsx we are stitching together the solution with requires and imports.
output
This is where we define where webpack should be dropping the file files it has found to bundle.
We have also defined a name for the file in which our bundled javascript and styles will be
dropped.
devServer
These are settings specific to webpack-dev-server. The contentBase defines where the server
http://java2aspire.com/ 37
should make it's root, we've defined the dist/ folder as our base here. The port is the port that the
server will be hosted on. open is what is used to instruct webpack-dev-server to open your default
browser for you once it's spun up the server.
This defines a mapping for webpack to use so that is knows what to do when it finds different files.
The test property gives regex for webpack to use to determine if it should apply this module, in
most cases we've matches on file extensions. loader or loaders give the name of the loader
module that we'd like to use to load the file into webpack and let that loader take care of the
bundling of that file type. There is also a query property on the javascript, this just provides a query
string to the loader, so we could have probably used a query property on the html loader as well if
we wanted to. It's just a different way of doing things.
Examples
How to build a pipeline for a customized "Hello world" with images.
The build pipeline you will be building is based in Node.js so you must ensure in the first instance
that you have this installed.
Open your project folder on the command line and use the following command:
npm init
Run the following command on the command line to install the packages necessary for this
example:
Finally webpack and webpack-dev-server are things that are worth installing globally rather than
as a dependency of your project, if you'd prefer to add it as a dependency then that will work to, I
don't. Here is the command to run:
http://java2aspire.com/ 38
npm install --global webpack webpack-dev-server
This will setup babel to use the presets you've just installed. Your .babelrc file should look like this:
{
"presets": ["react", "es2015"]
}
Set yourself up a directory stucture that looks like the below in the root of your directory:
|- node_modules
|- src/
|- components/
|- images/
|- styles/
|- index.html
|- index.jsx
|- .babelrc
|- package.json
NOTE: The node_modules, .babelrc and package.json should all have already been there from
previous steps I just included them so you can see where they fit.
Step 5: Populate the project with the Hello World project files
This isn't really important to the process of building a pipeline so I'll just give you the code for
these and you can copy paste them in:
src/components/HelloWorldComponent.jsx
handleChange(e) {
this.setState({name: e.target.value});
}
render() {
return (
<div>
<div className="image-container">
<img src="./images/myImage.gif" />
</div>
<div className="form">
<input type="text" onChange={this.handleChange} />
http://java2aspire.com/ 39
<div>
My name is {this.state.name} and I'm a clever cloggs because I built a React build
pipeline
</div>
</div>
</div>
);
}
}
src/images/myImage.gif
Feel free to substitute this with any image you'd like it's simply there to prove the point that we can
bundle up images as well. If you provide your own image and you name it something different then
you'll have to update the HelloWorldComponent.jsx to reflect your changes. Equally if you choose an
image with a different file extension then you need to modify the test property of the image loader
in the webpack.config.js with appropriate regex to match your new file extension..
src/styles/styles.css
.form {
margin: 25px;
padding: 25px;
border: 1px solid #ddd;
background-color: #eaeaea;
border-radius: 10px;
}
.form div {
padding-top: 25px;
}
.image-container {
display: flex;
justify-content: center;
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Learning to build a react pipeline</title>
</head>
<body>
<div id="content"></div>
<script src="app.js"></script>
</body>
</html>
index.jsx
http://java2aspire.com/ 40
import React from 'react';
import { render } from 'react-dom';
import HelloWorldComponent from './components/HelloWorldComponent.jsx';
require('./images/myImage.gif');
require('./styles/styles.css');
require('./index.html');
Create a file called webpack.config.js in the root of your project and copy this code into it:
webpack.config.js
var config = {
context: path.resolve( dirname + '/src'),
entry: './index.jsx',
output: {
filename: 'app.js',
path: path.resolve( dirname + '/dist'),
},
devServer: {
contentBase: path.join( dirname + '/dist'),
port: 3000,
open: true,
},
module: {
loaders: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loader: 'babel-loader'
},
{
test: /\.css$/,
loader: "style!css"
},
{
test: /\.gif$/,
loaders: [
'file?name=[path][name].[ext]',
'image-webpack',
]
},
{ test: /\.(html)$/,
loader: "file?name=[path][name].[ext]"
}
],
},
};
module.exports = config;
http://java2aspire.com/ 41
To do this you will need to add two properties to the scripts key of the JSON defined in the
package.json file in the root of your project. Make your scripts key look like this:
"scripts": {
"start": "webpack-dev-server",
"build": "webpack",
"test": "echo \"Error: no test specified\" && exit 1"
},
The test script will have already been there and you can choose whether to keep it or not, it's not
important to this example.
From the command line, if you are in the project root directory you should now be able to run the
command:
This will bundle up the little application you've built and place it in the dist/ directory that it will
create in the root of your project folder.
npm start
Then the application you've built will be served up in your default web browser inside of a webpack
dev server instance.
Installation
Simple setup
example/
|-- src/
| |-- index.js
| `-- ...
|-- out/
`-- package.json
http://java2aspire.com/ 42
code into es5 compliant code.
The above command will instruct npm to install the core babel libraries as well as the loader
module for use with webpack. We also install the es6 and react presets for babel to understand
JSX and es6 module code. (More information about the presets can be found here Babel presets)
$npm i -D webpack
This command will install webpack as a development dependency. (i is the shorthand for install
and -D the shorthand for --save-dev)
You might also want to install any additional webpack packages (such as additional loaders or the
webpack-dev-server extension)
Setting up webpack
With the dependencies setup we will need a webpack.config.js file to tell webpack what to do
http://java2aspire.com/ 43
simple webpack.config.js:
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve( dirname, 'out'),
filename: 'bundle.js'
},
module: {
loaders: [
{
test: /\.js$/,
exclude: /(node_modules)/,
loader: 'babel-loader',
query: {
presets: ['es2015', 'react']
}
}
]
}
};
This file tells webpack to start with the index.js file (assumed to be in src/ ) and convert it into a
single bundle.js file in the out directory.
The module block tells webpack to test all files encountered against the regular expression and if
they match, will invoke the specified loader. (babel-loader in this case) Furthermore, the exclude
regex tells webpack to ignore this special loader for all modules in the node_modules folder, this
helps speed up the transpilation process. Lastly, the query option tells webpack what parameters
to pass to babel and is used to pass along the presets we installed earlier.
src/index.js:
'use strict'
render(
<App />,
document. getElementById('app')
)
This file would normally render a simple <h1>Hello world!</h1> Header into the html tag with the id
http://java2aspire.com/ 44
'app', but for now it should be enough to transpile the code once.
$./node_modules/.bin/webpack . Will execute the locally installed version of webpack (use $webpack if
you installed webpack globally with -g)
This should create the file out/bundle.js with the transpiled code inside and concludes the
example.
Using webpack-dev-server
Setup
After setting up a simple project to use webpack, babel and react issuing $npm i -g webpack-dev-
server will install the development http server for quicker development.
Modifying webpack.config.js
var path = require('path');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve( dirname, 'out'),
publicPath: '/public/',
filename: 'bundle.js'
},
module: {
loaders: [
{
test: /\.js$/,
exclude: /(node_modules)/,
loader: 'babel',
query: {
presets: ['es2015', 'react']
}
}
]
},
devServer: {
contentBase: path.resolve( dirname, 'public'),
hot: true
}
};
• output.publicPath which sets up a path to have our bundle be served from (see Webpack
configuration files for more info)
• devServer
○ contentBase the base path to serve static files from (for example index.html)
http://java2aspire.com/ 45
○ hot sets the webpack-dev-server to hot reload when changes get made to files on disk
And finally we just need a simple index.html to test our app in.
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>React Sandbox</title>
</head>
<body>
<script src="public/bundle.js"></script>
</body>
</html>
With this setup running $webpack-dev-server should start a local http server on port 8080 and upon
connecting should render a page containing a <h1>Hello world!</h1>.
http://java2aspire.com/ 46
Introduction to Server-Side Rendering
Rendering components
There are two options to render components on server: renderToString and renderToStaticMarkup.
renderToString
This will render React components to HTML on server. This function will also add data-react-
properties to HTML elements so React on client won't have to render elements again.
renderToStaticMarkup
This will render React components to HTML, but without data-react- properties, it is not
recommended to use components that will be rendered on client, because components will
rerender.
http://java2aspire.com/ 47
JSX
Remarks
JSX is a preprocessor step that adds XML syntax to JavaScript. You can definitely use React
without JSX but JSX makes React a lot more elegant.
Just like XML, JSX tags have a tag name, attributes, and children. If an attribute value is enclosed
in quotes, the value is a string. Otherwise, wrap the value in braces and the value is the enclosed
JavaScript expression.
Fundamentally, JSX just provides syntactic sugar for the React.createElement(component, props,
...children) function.
In conclusion, note that the following line in JSX is neither a string nor HTML:
It is called JSX, and it is a syntax extension to JavaScript. JSX may remind you of a template
language, but it comes with the full power of JavaScript.
The React team says in their docs that they recommend using it to describe what the UI should
look like.
http://java2aspire.com/ 48
Examples
Props in JSX
JavaScript Expressions
You can pass any JavaScript expression as a prop, by surrounding it with {}. For example, in
this JSX:
Inside the MyComponent, the value of props.count will be 10, because the expression 1 + 2 + 3 +4
gets evaluated.
If statements and for loops are not expressions in JavaScript, so they can't be used in JSX
directly.
String Literals
Of course, you can just pass any string literal as a prop too. These two JSX expressions are
equivalent:
When you pass a string literal, its value is HTML-unescaped. So these two JSX expressions are
equivalent:
This behavior is usually not relevant. It's only mentioned here for completeness.
http://java2aspire.com/ 49
<MyTextBox autocomplete={true} />
However, the React team says in their docs using this approach is not recommended, because
it can be confused with the ES6 object shorthand {foo} which is short for {foo: foo} rather than
{foo: true}. They say this behavior is just there so that it matches the behavior of HTML.
Spread Attributes
If you already have props as an object, and you want to pass it in JSX, you can use ... as a
spread operator to pass the whole props object. These two components are equivalent:
function Case1() {
return <Greeting firstName="Kaloyab" lastName="Kosev" />;
}
function Case2() {
const person = {firstName: 'Kaloyan', lastName:
'Kosev'}; return <Greeting {...person} />;
}
Children in JSX
In JSX expressions that contain both an opening tag and a closing tag, the content between those
tags is passed as a special prop: props.children. There are several different ways to pass children:
String Literals
You can put a string between the opening and closing tags and props.children will just be that
string. This is useful for many of the built-in HTML elements. For example:
<MyComponent>
<h1>Hello world!</h1>
</MyComponent>
This is valid JSX, and props.children in MyComponent will simply be <h1>Hello world!</h1>.
Note that the HTML is unescaped, so you can generally write JSX just like you would write
HTML.
http://java2aspire.com/ 50
JSX Children
You can provide more JSX elements as the children. This is useful for displaying nested
components:
<MyContainer>
<MyFirstComponent />
<MySecondComponent />
</MyContainer>
You can mix together different types of children, so you can use string literals together with
JSX children. This is another way in which JSX is like HTML, so that this is both valid JSX and
valid HTML:
<div>
<h2>Here is a list</h2>
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
</div>
Note that a React component can't return multiple React elements, but a single JSX
expression can have multiple children. So if you want a component to render multiple things
you can wrap them in a div like the example above.
JavaScript Expressions
You can pass any JavaScript expression as children, by enclosing it within {}. For example, these
expressions are equivalent:
<MyComponent>foo</MyComponent>
<MyComponent>{'foo'}</MyComponent>
This is often useful for rendering a list of JSX expressions of arbitrary length. For example, this
renders an HTML list:
http://java2aspire.com/ 51
);
};
Note that JavaScript expressions can be mixed with other types of children.
Functions as Children
Normally, JavaScript expressions inserted in JSX will evaluate to a string, a React element, or a
list of those things. However, props.children works just like any other prop in that it can pass any
sort of data, not just the sorts that React knows how to render. For example, if you have a custom
component, you could have it take a callback as props.children:
Children passed to a custom component can be anything, as long as that component transforms
them into something React can understand before rendering. This usage is not common, but it
works if you want to stretch what JSX is capable of.
Ignored Values
Note that false, null, undefined, and true are valid children. But they simply don't render. These
JSX expressions will all render to the same thing:
<MyComponent />
<MyComponent></MyComponent>
<MyComponent>{false}</MyComponent>
<MyComponent>{null}</MyComponent>
<MyComponent>{true}</MyComponent>
This is extremely useful to conditionally render React elements. This JSX only renders a if
showHeader is true:
http://java2aspire.com/ 52
<div>
{showHeader && <Header />}
<Content />
</div>
One important caveat is that some "falsy" values, such as the 0 number, are still rendered by
React. For example, this code will not behave as you might expect because 0 will be printed when
props.messages is an empty array:
<div>
{props.messages.length &&
<MessageList messages={props.messages} />
}
</div>
One approach to fix this is to make sure that the expression before the && is always boolean:
<div>
{props.messages.length > 0 &&
<MessageList messages={props.messages} />
}
</div>
Lastly, bare in mind that if you want a value like false, true, null, or undefined to appear in the
output, you have to convert it to a string first:
<div>
My JavaScript variable is {String(myVariable)}.
</div>
Keys in react
Introduction
Keys in react are used to identify a list of DOM elements from the same hierarchy internally.
So if you are iterating over an array to show a list of li elements, each of the li elements needs a
unique identifier specified by the key property. This usually can be the id of your database item or
the index of the array.
Remarks
Using the array index as a key is generally not recommended when the array is going to change
over time. From the React Docs:
As a last resort, you can pass item's index in the array as a key. This can work well if
the items are never reordered, but reorders will be slow.
http://java2aspire.com/ 53
Examples
Using the id of an element
Here we are having a list of todo items that is passed to the props of our component.
Each todo item has a text and id property. Imagine that the id property comes from a backend
datastore and is a unique numeric value:
todos = [
{
id: 1,
text: 'value 1'
},
{
id: 2,
text: 'value 2'
},
{
id: 3,
text: 'value 3'
},
{
id: 4,
text: 'value 4'
},
];
http://java2aspire.com/ 54
We set the key attribute of each iterated list element to todo-${todo.id} so that react can identify it
internally:
render() {
const { todos } = this.props;
return (
<ul>
{ todos.map((todo) =>
<li key={ `todo-${todo.id}` }>
{ todo.text }
</li>
}
</ul>
);
}
If you don't have unique database ids at hand, you could also use the numeric index of your array
like this:
render() {
const { todos } = this.props;
return (
<ul>
{ todos.map((todo, index) =>
<li key={ `todo-${index}` }>
{ todo.text }
</li>
}
</ul>
);
}
Performance
The Basics - HTML DOM vs Virtual DOM
Each web page is represented internally as a tree of objects. This representation is called
Document Object Model. Moreover, it is a language-neutral interface that allows programming
languages (such as JavaScript) to access the HTML elements.
In other words
The HTML DOM is a standard for how to get, change, add, or delete HTML elements.
http://java2aspire.com/ 55
So React's team came up with the idea to abstract the HTML DOM and create its own Virtual
DOM in order to compute the minimum number of operations we need to apply on the HTML DOM
to replicate current state of our application.
How Exactly?
At each point of time, React has the application state represented as a Virtual DOM. Whenever
application state changes, these are the steps that React performs in order to optimise
performance
1. Generate a new Virtual DOM that represents the new state of our application
2. Compare the old Virtual DOM (which represents the current HTML DOM) vs the new Virtual
DOM
3. Based on 2. find the minimum number of operations to transform the old Virtual DOM (which
represents the current HTML DOM) into the new Virtual DOM
4. After those operations are found, they are mapped into their equivalent HTML DOM
operations
• remember, the Virtual DOM is only an abstraction of the HTML DOM and there is a
http://java2aspire.com/ 56
isomorphic relation between them
5. Now the minimum number of operations that have been found and transferred to their
equivalent HTML DOM operations are now applied directly onto the application's HTML
DOM, which saves time from modifying the HTML DOM unnecessarily.
Note: Operations applied on the Virtual DOM are cheap, because the Virtual DOM is a JavaScript
Object.
Generating the minimum number of operations to transform one tree into another have a
complexity in the order of O(n^3) where n is the number of nodes in the tree. React relies on two
assumptions to solve this problem in a linear time - O(n)
1. Two components of the same class will generate similar trees and tw
components of different classes will generate different trees.
2. It is possible to provide a unique key for elements that is stable across different
renders.
Moreover, what follows is crucial and extremely important to understand if you want to
optimise performance
If they [two nodes] are not of the same type, React is not going to even try at matching
what they render. It is just going to remove the first one from the DOM and insert the
second one.
Here's why
It is very unlikely that a element is going to generate a DOM that is going to look like
what a would generate. Instead of spending time trying to match those two structures,
React just re-builds the tree from scratch.
When two nodes are not of the same type, React doesn't try to match them - it just removes the
first node from the DOM and inserts the second one. This is why the first tip says
1. If you see yourself alternating between two components classes with very similar output, you
http://java2aspire.com/ 57
may want to make it the same class.
You can't improve something you can't measure. To improve the performance of React
components, you should be able to measure it. ReactJS provides with addon tools to measure
performance. Import the react-addons-perf module to measure the performance
You can use below methods from the imported Perf module:
• Perf.printInclusive()
• Perf.printExclusive()
• Perf.printWasted()
• Perf.printOperations()
• Perf.printDOM()
The most important one which you will need most of the time is Perf.printWasted() which gives you
the tabular representation of your individual component's wasted time
You can note the Wasted time column in the table and improve Component's performance using
Tips & Tricks section above
Refer the React Official Guide and excellent article by Benchling Engg. on React Performance
http://java2aspire.com/ 58
Props in React
Remarks
NOTE: As of React 15.5 and up the PropTypes component lives in its own npm package, namely
'prop-types' and needs its own import statement when using PropTypes. See the official react
documentation for the breaking change: https://facebook.github.io/react/blog/2017/04/07/react-
v15.5.0.html
Examples
Introduction
props are used to pass data and methods from a parent component to a child component.
Basic example
http://java2aspire.com/ 59
As you can see in the example, thanks to props we can create reusable components.
Default props
defaultProps allows you to set default, or fallback, values for your component props. defaultProps
are useful when you call components from different views with fixed props, but in some views you
need to pass different value.
Syntax
ES5
ES6
MyClass.defaultProps = {
randomObject: {},
...
}
ES7
The result of getDefaultProps() or defaultProps will be cached and used to ensure that
this.props.randomObject will have a value if it was not specified by the parent component.
PropTypes
propTypes allows you to specify what props your component needs and the type they should be.
Your component will work without setting propTypes, but it is good practice to define these as it will
make your component more readable, act as documentation to other developers who are reading
your component, and during development, React will warn you if you you try to set a prop which is
a different type to the definition you have set for it.
http://java2aspire.com/ 60
Some primitive propTypes and commonly useable propTypes are -
optionalArray: React.PropTypes.array,
optionalBool: React.PropTypes.bool,
optionalFunc: React.PropTypes.func,
optionalNumber: React.PropTypes.number,
optionalObject: React.PropTypes.object,
optionalString: React.PropTypes.string,
optionalSymbol: React.PropTypes.symbol
If you attach isRequired to any propType then that prop must be supplied while creating the instance
of that component. If you don't provide the required propTypes then component instance can not
be created.
Syntax
ES5
ES6
MyClass.propTypes = {
randomObject: React.PropTypes.object,
callback: React.PropTypes.func.isRequired,
...
};
ES7
In the same way, PropTypes allows you to specify more complex validation
http://java2aspire.com/ 61
Validating an object
...
randomObject: React.PropTypes.shape({
id: React.PropTypes.number.isRequired,
text: React.PropTypes.string,
}).isRequired,
...
...
arrayOfObjects: React.PropTypes.arrayOf(React.PropTypes.shape({
id: React.PropTypes.number.isRequired,
text: React.PropTypes.string,
})).isRequired,
...
Instead of
Where each property needs to be passed as a single prop value you could use the spread
operator ... supported for arrays in ES6 to pass down all your values. The component will now
look like this.
Remember that the properties of the object that you pass in are copied onto the component's
props.
Another case is that you also can use spread operator to pass only parts of props to children
components, then you can use destructuring syntax from props again.
It's very useful when children components need lots of props but not want pass them one by one.
const { foo, bar, other } = this.props // { foo: 'foo', bar: 'bar', other: 'other' };
var component = <Component {...{foo, bar}} />;
const { foo, bar } = component.props
console.log(foo, bar); // 'foo bar'
http://java2aspire.com/ 62
The "child" components of a component are available on a special prop, props.children. This prop
is very useful for "Compositing" components together, and can make JSX markup more intuitive or
reflective of the intended final structure of the DOM:
Which allows us to include an arbitrary number of sub-elements when using the component later:
Props.children can also be manipulated by the component. Because props.children may or may
not be an array, React provides utility functions for them as React.Children. Consider in the
previous example if we had wanted to wrap each paragraph in its own <section> element:
Note the use of React.cloneElement to remove the props from the child <p> tag - because props
are immutable, these values cannot be changed directly. Instead, a clone without these props
must be used.
Additionally, when adding elements in loops, be aware of how React reconciles children during a
rerender, and strongly consider including a globally unique key prop on child elements added in a
loop.
http://java2aspire.com/ 63
Detecting the type of Children components
Sometimes it's really useful to know the type of child component when iterating through them. In
order to iterate through the children components you can use React Children.map util function:
The child object exposes the type property which you can compare to a specific component.
http://java2aspire.com/ 64
React AJAX call
Examples
HTTP GET request
Sometimes a component needs to render some data from a remote endpoint (e.g. a REST API). A
standard practice is to make such calls in componentDidMount method.
A request can be initiated by invoking the appropriate method on the request object, then calling
.end() to send the request. Setting header fields is simple, invoke .set() with a field name and
value.
The .query() method accepts objects, which when used with the GET method will form a query-
string. The following will produce the path /search?query=Manny&range=1..5&order=desc.
POST requests
request.post('/user')
.set('Content-Type', 'application/json')
http://java2aspire.com/ 65
.send('{"name":"tj","pet":"tobi"}')
.end(callback)
request.onload = () => {
if (request.status >= 200 && request.status < 400) {
// Success!
this.setState({someData: request.responseText})
} else {
// We reached our target server, but it returned an error
// Possibly handle the error by changing your state.
}
};
request.onerror = () => {
// There was a connection error of some sort.
// Possibly handle the error by changing your state.
};
request.send();
},
render() {
return (
<div>{this.state.someData || 'waiting for response...'}</div>
)
}
}
The following example shows how a set of data obtained from a remote source can be rendered
into a component.
We make an AJAX request using fetch, which is build into most browsers. Use a fetch polyfill in
production to support older browsers. You can also use any other library for making requests (e.g.
axios, SuperAgent, or even plain Javascript).
We set the data we receive as component state, so we can access it inside the render method.
http://java2aspire.com/ 66
There, we loop through the data using map. Don't forget to always add a unique key attribute (or
prop) to the looped element, which is important for React's rendering performance.
componentDidMount() {
fetch('/api/users')
.then(response => response.json())
.then(json => this.setState({ users: json.data }));
}
render() {
return (
<div>
<h1>Users</h1>
{
this.state.users.length == 0
? 'Loading users...'
: this.state.users.map(user => (
<figure key={user.id}>
<img src={user.avatar} />
<figcaption>
{user.name}
</figcaption>
</figure>
))
}
</div>
);
}
}
http://java2aspire.com/ 67
React Boilerplate [React + Babel
+ Webpack]
Setting up the project
You need Node Package Manager to install the project dependencies. Download node for your
operating system from Nodejs.org. Node Package Manager comes with node.
You can also use Node Version Manager to better manage your node and npm versions. It is
great for testing your project on different node versions. However, it is not recommended for
production environment.
Once you have installed node on your system, go ahead and install some essential packages to
blast off your first React project using Babel and Webpack.
Before we actually start hitting commands in the terminal. Take a look at what Babel and Webpack
are used for.
You can start your project by running npm init in your terminal. Follow the initial setup. After that,
run following commands in your terminal-
Dependencies:
Dev Dependecies:
{
"presets": ["es2015", "stage-0", "react"]
}
{
"ecmaFeatures": {
"jsx": true,
http://java2aspire.com/ 68
"modules": true
},
"env": {
"browser": true,
"node": true
},
"parser": "babel-eslint",
"rules": {
"quotes": [2, "single"],
"strict": [2, "never"],
},
"plugins": [
"react"
]
}
Create a .gitignore file to prevent uploading generated files to your git repo.
node_modules
npm-debug.log
.DS_Store
dist
module.exports = {
devtool: 'eval',
entry: [
'webpack-dev-server/client?http://localhost:3000',
'webpack/hot/only-dev-server',
'./src/index'
],
output: {
path: path.join( dirname, 'dist'),
filename: 'bundle.js',
publicPath: '/static/'
},
plugins: [
new webpack.HotModuleReplacementPlugin()
],
module: {
loaders: [{
test: /\.js$/,
loaders: ['react-hot', 'babel'],
include: path.join( dirname, 'src')
}]
}
};
And finally, create a sever.js file to be able to run npm start, with following contents:
http://java2aspire.com/ 69
new WebpackDevServer(webpack(config), {
publicPath: config.output.publicPath,
hot: true,
historyApiFallback: true
}).listen(3000, 'localhost', function (err, result) {
if (err) {
return console.log(err);
}
Run node server.js or npm start in the terminal, if you have defined what start stands for in your
package.json
react-starter project
This is simple boilerplate project. This post will guide you to set up the environment for ReactJs +
Webpack + Bable.
we will need node package manager for fire up express server and manage dependencies
throughout the project. if you are new to node package manager, you can check here. Note :
Installing node package manager is require here.
Create a folder with suitable name and navigate into it from terminal or by GUI.Then go to terminal
and type npm init this will create a package.json file, Nothing scary , it will ask you few question
like name of your project ,version, description, entry point, git repository, author, license etc. Here
entry point is important because node will initially look for it when you run the project. At the end it
will ask you to verify the information you provide. You can type yes or modify it. Well that's it , our
package.json file is ready.
Express server setup run npm install express@4 --save. This is all the dependencies we needed
for this project.Here save flag is important, without it package.js file will not be updated. Main task
of package.json is to store list of dependencies. It will add express version 4. Your package.json
will look like "dependencies": { "express": "^4.13.4",...............},
http://java2aspire.com/ 70
After complete download you can see there is node_modules folder and sub folder of our
dependencies. Now on the root of project create new file server.js file. Now we are setting express
server. I am going to past all the code and explain it later.
app.use(express.static('public'));
app.listen(3000, function () {
console.log('Express server is using port:3000');
});
var express = require('express'); this will gave you the access of entire express api.
var app = express(); will call express library as function. app.use(); let the add the functionality to
your express application. app.use(express.static('public')); will specify the folder name that will be
expose in our web server. app.listen(port, function(){}) will here our port will be 3000 and function
we are calling will verify that out web server is running properly. That's it express server is set up.
Now go to our project and create a new folder public and create index.html file. index.html is the
default file for you application and Express server will look for this file. The index.html is simple
html file which looks like
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
</head>
<body>
<h1>hello World</h1>
</body>
</html>
And go to the project path through the terminal and type node server.js. Then you will see *
console.log('Express server is using port:3000');*.
Go to the browser and type http://localhost:3000 in nav bar you will see hello World.
Now go inside the public folder and create a new file app.jsx. JSX is a preprocessor step that adds
XML syntax to your JavaScript.You can definitely use React without JSX but JSX makes React a
lot more elegant. Here is the sample code for app.jsx
ReactDOM.render(
<h1>Hello World!!!</h1>,
document.getElementById('app')
);
Now go to index.html and modify the code , it should looks like this
http://java2aspire.com/ 71
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23
/browser.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react.js">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-dom.js"> </script>
</head>
<body>
<div id="app"></div>
</html>
With this in place you are all done, I hope you find it simple.
http://java2aspire.com/ 72
React Component Lifecycle
Introduction
Lifecycle methods are to be used to run code and interact with your component at different points
in the components life. These methods are based around a component Mounting, Updating, and
Unmounting.
Examples
Component Creation
• If you are using React.createClass (ES5), 5 user defined functions are called
• If you are using class Component extends React.Component (ES6), 3 user defined functions are
called
Prop values returned by this function will be used as defaults if they are not defined when the
component is instantiated.
In the following example, this.props.name will be defaulted to Bob if not specified otherwise:
getDefaultProps() {
return {
initialCount: 0,
name: 'Bob'
};
}
The return value of getInitialState() defines the initial state of the React component. The React
framework will call this function and assign the return value to this.state.
http://java2aspire.com/ 73
getInitialState() {
return {
count : this.props.initialCount
};
}
This function can be used to make final changes to the component before it will be added to the
DOM.
componentWillMount() {
...
}
The render() function should be a pure function of the component's state and props. It returns a
single element which represents the component during the rendering process and should either be
a representation of a native DOM component (e.g. <p />) or a composite component. If nothing
should be rendered, it can return null or undefined.
This function will be recalled after any change to the component's props or state.
render() {
return (
<div>
Hello, {this.props.name}!
</div>
);
}
The component has been mounted and you are now able to access the component's DOM nodes,
e.g. via refs.
• Preparing timers
• Fetching data
http://java2aspire.com/ 74
• Adding event listeners
• Manipulating DOM elements
componentDidMount() {
...
}
ES6 Syntax
If the component is defined using ES6 class syntax, the functions getDefaultProps() and
getInitialState() cannot be used.
Instead, we declare our defaultProps as a static property on the class, and declare the state shape
and initial state in the constructor of our class. These are both set on the instance of the class at
construction time, before any other React lifecycle function is called.
this.state = {
count: this.props.initialCount
};
}
upCount() {
this.setState((prevState) => ({
count: prevState.count + 1
}));
}
render() {
return (
<div>
Hello, {this.props.name}!<br />
You clicked the button {this.state.count} times.<br />
<button onClick={this.upCount}>Click here!</button>
</div>
);
}
}
MyReactClass.defaultProps = {
name: 'Bob',
initialCount: 0
};
Replacing getDefaultProps()
Default values for the component props are specified by setting the defaultProps property of the
class:
http://java2aspire.com/ 75
MyReactClass.defaultProps = {
name: 'Bob',
initialCount: 0
};
Replacing getInitialState()
The idiomatic way to set up the initial state of the component is to set this.state in the constructor:
constructor(props){
super(props);
this.state = {
count: this.props.initialCount
};
}
Component Update
componentWillReceiveProps(nextProps)
When component's properties change, React will call this function with the new properties.
You can access to the old props with this.props and to the new props with nextProps.
With these variables, you can do some comparison operations between old and new props, or call
function because a property change, etc.
componentWillReceiveProps(nextProps){
if (nextProps.initialCount && nextProps.initialCount > this.state.count){
this.setState({
count : nextProps.initialCount
});
}
}
shouldComponentUpdate(nextProps, nextState)
This is the second function called on properties changes and the first on state changes.
By default, if another component / your component change a property / a state of your component,
React will render a new version of your component. In this case, this function always return true.
You can override this function and choose more precisely if your component must update or
not.
In case of the function returns false, the update pipeline stops immediately.
http://java2aspire.com/ 76
componentShouldUpdate(nextProps, nextState){
return this.props.name !== nextProps.name ||
this.state.count !== nextState.count;
}
componentWillUpdate(nextProps, nextState)
This function works like componentWillMount(). Changes aren't in DOM, so you can do some
changes just before the update will perform.
componentWillUpdate(nextProps, nextState){}
render()
Same stuff as componentDidMount() : DOM is refreshed, so you can do some work on the DOM
here.
componentDidUpdate(prevProps, prevState){}
Component Removal
componentWillUnmount()
componentWillUnmount(){
...
}
constructor(props) {
http://java2aspire.com/ 77
super(props);
this.state = {
...
};
this.openMenu = this.openMenu.bind(this);
this.closeMenu = this.closeMenu.bind(this);
}
componentDidMount() {
document.addEventListener("click", this.closeMenu);
}
componentWillUnmount() {
document.removeEventListener("click", this.closeMenu);
}
openMenu() {
...
}
closeMenu() {
...
}
render() {
return (
<div>
<a
href = "javascript:void(0)"
className = "closebtn"
onClick = {this.closeMenu}
>
×
</a>
<div>
Some other structure
</div>
</div>
);
}
}
When building a React application, it is often desirable to divide components based on their
primary responsibility, into Presentational and Container components.
Presentational components are concerned only with displaying data - they can be regarded as,
and are often implemented as, functions that convert a model to a view. Typically they do not
maintain any internal state. Container components are concerned with managing data. This may
be done internally through their own state, or by acting as intermediaries with a state-management
library such as Redux. The container component will not directly display data, rather it will pass the
data to a presentational component.
// Container component
import React, { Component } from 'react';
import Api from 'path/to/api';
http://java2aspire.com/ 78
class CommentsListContainer extends Component {
constructor() {
super();
// Set initial state
this.state = { comments: [] }
}
componentDidMount() {
// Make API call and update state with returned comments
Api.getComments().then(comments => this.setState({ comments }));
}
render() {
// Pass our state comments to the presentational component
return (
<CommentsList comments={this.state.comments} />;
);
}
}
// Presentational Component
const CommentsList = ({ comments }) => (
<div>
{comments.map(comment => (
<div>{comment}</div>
)}
</div>
);
CommentsList.propTypes = {
comments: React.PropTypes.arrayOf(React.PropTypes.string)
}
This example serves as a complement to other examples which talk about how to use the lifecycle
methods and when the method will be called.
1. getDefaultProps
2. getInitialState
3. componentWillMount
4. render
5. componentDidMount
1. shouldComponentUpdate
2. componentWillUpdate
3. render
4. componentDidUpdate
http://java2aspire.com/ 79
When a component has props changed:
1. componentWillReceiveProps
2. shouldComponentUpdate
3. componentWillUpdate
4. render
5. componentDidUpdate
1. componentWillUnmount
React Forms
Controlled Components
A controlled component is bound to a value and its changes get handled in code using event
based callbacks.
handleChange(event) {
let person = this.state.person;
person[event.target.name] = event.target.value;
this.setState({person});
}
render() {
return (
<form>
<input
type="text"
name="firstName"
value={this.state.firstName}
onChange={this.handleChange.bind(this)} />
<input
type="text"
name="lastName"
value={this.state.lastName}
onChange={this.handleChange.bind(this)} />
</form>
)
}
http://java2aspire.com/ 80
In this example we initialize state with an empty person object. We then bind the values of the 2
inputs to the individual keys of the person object. Then as the user types, we capture each value
in the handleChange function. Since the values of the components are bound to state we can
rerender as the user types by calling setState().
NOTE: Not calling setState() when dealing with controlled components, will cause the user to
type, but not see the input because React only renders changes when it is told to do so.
http://java2aspire.com/ 81
It's also important to note that the names of the inputs are same as the names of the keys in the
person object. This allows us to capture the value in dictionary form as seen here.
handleChange(event) {
let person = this.state.person;
person[event.target.name] = event.target.value;
this.setState({person});
}
http://java2aspire.com/ 82
React Routing
Example Routes.js file, followed by use of Router Link in component
Place a file like the following in your top level directory. It defines which components to
render for which paths
export default(
<Route path="/" component={App}>
<IndexRoute component={Index} />
<Route path="posts/new" component={New} />
<Route path="posts/:id" component={Show} />
</Route>
);
Now in your top level index.js that is your entry point to the app, you need only render this
Router component like so:
// entry point
ReactDOM.render(
<Router history={browserHistory} routes={routes} />
, document.getElementById('main'));
Now it is simply a matter of using Link instead of <a> tags throughout your application.
Using Link will communicate with React Router to change the React Router route to the
specified link, which will in turn render the correct component as defined in routes.js
http://java2aspire.com/ 83
<div className="post-button" >
{props.title}
<span>{props.tags}</span>
</div>
</Link>
);
}
http://java2aspire.com/ 84
React Tools
Links
http://java2aspire.com/ 85
React with Redux
Introduction
Redux has come to be the status quo for managing application-level state on the front-end these
days, and those who work on "large-scale applications" often swear by it. This topic covers why
and how you should use the state management library, Redux, in your React applications.
Remarks
While React's component driven architecture is fantastic for breaking down the application into
modular, encapsulated little pieces, it introduces some challenges for managing the state of the
application as a whole. The time to use Redux is when you need to display the same data across
more than one component or page (aka route). At that point you can no longer store the data in
variables local to one component or the other, and sending messages between components
quickly becomes a mess. With Redux your components are all subscribing to the same shared
data in the store and thus the state can be easily reflected consistently across the entire
application.
Examples
Using Connect
Use connect to connect component to Redux store and pull props from store to component.
Define actions that allow your components to send messages to the Redux store.
/*
* action types
*/
http://java2aspire.com/ 86
export function addTodo(text) {
return { type: ADD_TODO, text }
}
Handle these messages and create a new state for the store in reducer functions.
http://java2aspire.com/ 87
React, Webpack & Typescript installation
Remarks
To get syntax highlighting in your editor (e.g. VS Code) you'll need to download typing information
for the modules that you use in your project.
Say for example you use React and ReactDOM in your project, and you want to get highlighting
and Intellisense for them. You will need to add the types to your project using this command:
Your editor should now automatically pick up on on this typing information and supply you with
autocomplete and Intellisense for these modules.
Examples
webpack.config.js
module.exports = {
entry: './src/index',
output: {
path: dirname + '/build',
filename: 'bundle.js'
},
module: {
rules: [{
test: /\.tsx?$/,
loader: 'ts-loader',
exclude: /node_modules/
}]
},
resolve: {
extensions: ['.ts', '.tsx']
}
};
The main components are (in addition to the standard entry, output and other webpack properties):
The loader
For this you need to create a rule that tests for the .ts and .tsx file extensions, specify ts-loader
as the loader.
http://java2aspire.com/ 88
Resolve TS extensions
You also need to add the .ts and .tsx extensions in the resolve array, or webpack won't see them.
tsconfig.json
{
"include": [
"src/*"
],
"compilerOptions": {
"target": "es5",
"jsx": "react",
"allowSyntheticDefaultImports": true
}
}
include
This is an array of source code. Here we have only one entry, src/*, which specifies that
everything in the src directory is to be included in compilation.
compilerOptions.target
compilerOptions.jsx
Setting this to true will make TypeScript automatically compile your tsx syntax from <div /> to
React.createElement("div").
compilerOptions.allowSyntheticDefaultImports
Handy property which will allow you to import node modules as if they are ES6 modules, so
instead of doing
without any errors telling you that React has no default export.
http://java2aspire.com/ 89
My First Component
interface AppProps {
name: string;
}
interface AppState {
words: string[];
}
render() {
const { name } = this.props;
return (<h1>Hello {name}!</h1>);
}
}
When using TypeScript with React, once you've downloaded the React DefinitelyTyped type
definitions (npm install --save @types/react), every component will require you to add type
annotations.
where AppProps and AppState are interfaces (or type aliases) for your components' props and state
respectively.
http://java2aspire.com/ 90
React.createClass vs extends
React.Component
Syntax
• Case 1: React.createClass({ })
• Case 2: class MyComponent extends React.Component { }
Remarks
was deprecated in v15.5 and expected to be removed in v16. There is a drop-in
React.createClass
replacement package for those that still require it. Examples using it should be updated.
Examples
Create React Component
React.createClass (deprecated)
Here we have a const with a React class assigned, with the render function following on to
complete a typical base component definition.
React.Component
Let's take the above React.createClass definition and convert it to use an ES6 class.
http://java2aspire.com/ 91
render() {
return (
<div></div>
);
}
}
In this example we're now using ES6 classes. For the React changes, we now create a class
called MyComponent and extend from React.Component instead of accessing React.createClass
directly. This way, we use less React boilerplate and more JavaScript.
PS: Typically this would be used with something like Babel to compile the ES6 to ES5 to work in
other browsers.
There are important changes in how we use and declare default props and their types.
React.createClass
In this version, the propTypes property is an Object in which we can declare the type for each prop.
The getDefaultProps property is a function that returns an Object to create the initial props.
React.Component
This version uses propTypes as a property on the actual MyComponent class instead of a property
as part of the createClass definition Object.
http://java2aspire.com/ 92
The getDefaultProps has now changed to just an Object property on the class called defaultProps,
as it's no longer a "get" function, it's just an Object. It avoids more React boilerplate, this is just
plain JavaScript.
Additionally, there is another syntax for propTypes and defaultProps. This is a shortcut if your build
has ES7 property initializers turned on:
http://java2aspire.com/ 93
React.createClass
We have a getInitialState function, which simply returns an Object of initial states.
React.Component
In this version we declare all state as a simple initialisation property in the constructor, instead
of using the getInitialState function. It feels less "React API" driven since this is just plain
JavaScript.
Mixins
React.createClass
In this version we can add mixins to components using the mixins property which takes an Array of
http://java2aspire.com/ 94
available mixins. These then extend the component class.
var MyMixin = {
doSomething() {
}
};
const MyComponent = React.createClass({
mixins: [MyMixin],
handleClick() {
this.doSomething(); // invoke mixin's method
},
render() {
return (
<button onClick={this.handleClick}>Do Something</button>
);
}
});
React.Component
React mixins are not supported when using React components written in ES6. Moreover, they will
not have support for ES6 classes in React. The reason is that they are considered harmful.
"this" Context
Using React.createClass will automatically bind this context (values) correctly, but that is not the
case when using ES6 classes.
React.createClass
Note the onClick declaration with the this.handleClick method bound. When this method gets
called React will apply the right execution context to the handleClick.
http://java2aspire.com/ 95
return (
<div onClick={this.handleClick}></div>
);
}
});
React.Component
With ES6 classes this is null by default, properties of the class do not automatically bind to the
React class (component) instance.
There are a few ways we could bind the right this context.
http://java2aspire.com/ 96
Case 2: Bind in the class constructor
Another approach is changing the context of this.handleClick inside the constructor. This way we
avoid inline repetition. Considered by many as a better approach that avoids touching JSX at all:
http://java2aspire.com/ 97
searchResults: []
};
}
showResults(response){
this.setState({
searchResults: response.results
})
}
search(url){
$.ajax({
type: "GET",
dataType: 'jsonp',
url: url,
success: (data) => {
this.showResults(data);
},
error: (xhr, status, err) => {
console.error(url, status, err.toString());
}
});
}
render() {
return (
<div>
<SearchBox search={this.search.bind(this)} />
<Results searchResults={this.state.searchResults} />
</div>
);
}
}
Filename: src/index.jsx
http://java2aspire.com/ 98
# install react and react-dom
$ npm i react react-dom --save
Configure webpack
Filename: webpack.config.js
module.exports = {
entry: dirname + "/src/index.jsx",
devtool: "source-map",
output: {
path: dirname + "/build",
filename: "bundle.js"
},
module: {
loaders: [
http://java2aspire.com/ 99
{test: /\.jsx?$/, exclude: /node_modules/, loader: "babel-loader"}
]
}
}
Configure babel
Filename: .babelrc
{
"presets": ["es2015","react"]
}
Filename: index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="App"></div>
<script src="build/bundle.js" charset="utf-8"></script>
</body>
</html>
$ webpack
State in React
Basic State
State in React components is essential to manage and communicate data in your application. It is
represented as a JavaScript object and has component level scope, it can be thought of as the
private data of your component.
In the example below we are defining some initial state in the constructor function of our
component and make use of it in the render function.
http://java2aspire.com/ 100
class ExampleComponent extends React.Component {
constructor(props){
super(props);
render() {
// We can access the greeting property through
this.state return(
<div>{this.state.greeting}</div>
);
}
}
setState()
The primary way that you make UI updates to your React applications is through a call to the
setState() function. This function will perform a shallow merge between the new state that you
provide and the previous state, and will trigger a re-render of your component and all decedents.
Parameters
1. updater: It can be an object with a number of key-value pairs that should be merged into the
state or a function that returns such an object.
2. callback (optional): a function which will be executed after setState() has been executed
successfully. Due to the fact that calls to setState() are not guaranteed by React to be
atomic, this can sometimes be useful if you want to perform some action after you are
positive that setState() has been executed successfully.
Usage:
The setState method accepts an updater argument that can either be an object with a number of
http://java2aspire.com/ 101
key-value-pairs that should be merged into the state, or a function that returns such an object
computed from prevState and props.
//
// An example ES6 style component, updating the state on a simple button click.
// Also demonstrates where the state can be set directly and where setState should be used.
//
class Greeting extends React.Component {
constructor(props) {
super(props);
this.click = this.click.bind(this);
// Set initial state (ONLY ALLOWED IN CONSTRUCTOR)
this.state = {
greeting: 'Hello!'
};
}
click(e) {
this.setState({
greeting: 'Hello World!'
});
}
render() {
return(
<div>
<p>{this.state.greeting}</p>
<button onClick={this.click}>Click me</button>
</div>
);
}
//
// This is most often used when you want to check or make use
// of previous state before updating any values.
//
this.setState(function(previousState, currentProps) {
return {
counter: previousState.counter + 1
};
});
This can be safer than using an object argument where multiple calls to setState() are used, as
multiple calls may be batched together by React and executed at once, and is the preferred
approach when using current props to set state.
http://java2aspire.com/ 102
this.setState({ counter: this.state.counter + 1 });
this.setState({ counter: this.state.counter + 1 });
These calls may be batched together by React using Object.assign(), resulting in the counter
being incremented by 1 rather than 3.
The functional approach can also be used to move state setting logic outside of components. This
allows for isolation and re-use of state logic.
// Within component
this.setState(incrementCounter);
Common Antipattern
You should not save props into state. It is considered an anti-pattern. For example:
this.state = {
url: ''
}
this.onChange = this.onChange.bind(this);
}
onChange(e) {
this.setState({
url: this.props.url + '/days=?' + e.target.value
});
}
componentWillMount() {
http://java2aspire.com/ 103
this.setState({url: this.props.url});
}
render() {
return (
<div>
<input defaultValue={2} onChange={this.onChange} />
URL: {this.state.url}
</div>
)
}
}
The prop url is saved on state and then modified. Instead, choose to save the changes to a state,
and then build the full path using both state and props:
this.state = {
days: ''
}
this.onChange = this.onChange.bind(this);
}
onChange(e) {
this.setState({
days: e.target.value
});
}
render() {
return (
<div>
<input defaultValue={2} onChange={this.onChange} />
This is because in a React application we want to have a single source of truth - i.e. all data is the
responsibility of one single component, and only one component. It is the responsibility of this
component to store the data within its state, and distribute the data to other components via props.
In the first example, both the MyComponent class and its parent are maintaining 'url' within their
state. If we update state.url in MyComponent, these changes are not reflected in the parent. We
have lost our single source of truth, and it becomes increasingly difficult to track the flow of data
through our application. Contrast this with the second example - url is only maintained in the state
of the parent component, and utilised as a prop in MyComponent - we therefore maintain a single
source of truth.
http://java2aspire.com/ 104
State, Events And Managed Controls
Here's an example of a React component with a "managed" input field. Whenever the value of the
input field changes, an event handler is called which updates the state of the component with the
new value of the input field. The call to setState in the event handler will trigger a call to render
updating the component in the dom.
constructor(props){
super(props);
this.state = {message: ""};
}
handleChange(e){
this.setState({message: e.target.value});
}
render() {
return (
<div>
<legend>Type something here</legend>
<input
onChange={this.handleChange.bind(this)}
value={this.state.message}
autoFocus />
<h1>{this.state.message}</h1>
</div>
);
}
}
render(<ManagedControlDemo/>, document.querySelector('#app'));
Its very important to note the runtime behavior. Everytime a user changes the value in the input
field
Pop quiz, after you type a character in the input field, which DOM elements change
You can experiment with this more here to find the answer
http://java2aspire.com/ 105
Stateless Functional
Components
Remarks
Stateless functional components in React are pure functions of the passed in props. These
components do not rely on state and discard the use of component lifecycle methods. You may,
however, still define propTypes and defaultPropts.
Examples
Stateless Functional Component
Components let you split the UI into independent, reusable pieces. This is the beauty of React; we
can separate a page into many small reusable components.
Prior to React v14 we could create a stateful React component using React.Component (in ES6), or
React.createClass (in ES5), irrespective of whether it requires any state to manage data or not.
React v14 introduced a simpler way to define components, usually referred to as stateless
functional components. These components use plain JavaScript functions.
For example:
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
This function is a valid React component because it accepts a single props object argument with
data and returns a React element. We call such components functional because they are literally
JavaScript functions.
Stateless functional components typically focus on UI; state should be managed by higher-level
“container” components, or via Flux/Redux etc. Stateless functional components don’t support
state or lifecycle methods.
Benefits:
1. No class overhead
2. Don't have to worry about this keyword
3. Easy to write and easy to understand
4. Don't have to worry about managing state values
http://java2aspire.com/ 106
5. Performance improvement
Summary: If you are writing a React component that doesn't require state and would like to create
a reusable UI, instead of creating a standard React Component you can write it as a stateless
functional component.
Let's say we have a page that can register a user, search for registered users, or display a list of
all the registered users.
ReactDOM.render(
<HomePage/>,
document.getElementById('app')
);
The HomePage component provides the UI to register and search for users. Note that it is a typical
React component including state, UI, and behavioral code. The data for the list of registered users
is stored in the state variable, but our reusable List (shown below) encapsulates the UI code for
the list.
homepage.js:
constructor(props) {
super();
this.state={users:[], showSearchResult: false, searchResult: []};
}
registerClick(){
let users = this.state.users.slice();
if(users.indexOf(this.refs.mail_id.value) == -1){
users.push(this.refs.mail_id.value);
this.refs.mail_id.value = '';
this.setState({users});
}else{
alert('user already registered');
}
}
searchClick(){
let users = this.state.users;
let index = users.indexOf(this.refs.search.value);
http://java2aspire.com/ 107
if(index >= 0){
this.setState({searchResult: users[index], showSearchResult: true});
}else{
alert('no user found with this mail id');
}
}
hideSearchResult(){
this.setState({showSearchResult: false});
}
render() {
return (
<div>
<input placeholder='email-id' ref='mail_id'/>
<input type='submit' value='Click here to register'
onClick={this.registerClick.bind(this)}/>
<input style={{marginLeft: '100px'}} placeholder='search' ref='search'/>
<input type='submit' value='Click here to register'
onClick={this.searchClick.bind(this)}/>
{this.state.showSearchResult ?
<div>
Search Result:
<List users={[this.state.searchResult]}/>
<p onClick={this.hideSearchResult.bind(this)}>Close this</p>
</div>
:
<div>
Registered users:
<br/>
{this.state.users.length ?
<List users={this.state.users}/>
:
"no user is registered"
}
</div>
}
</div>
);
}
}
Finally, our stateless functional component List, which is used display both the list of registered
users and the search results, but without maintaining any state itself.
list.js:
https://riptutorial.com/ 110
);
})
}
</div>
);
}
Reference: https://facebook.github.io/react/docs/components-and-props.html
Examples
Basic Pane
render() {
return React.createElement(
'section', this.props
);
}
}
Panel
https://riptutorial.com/ 109
import React from 'react';
render(...elements) {
var props = Object.assign({
className: this.props.active ? 'active' : '',
tabIndex: -1
}, this.props);
return React.createElement(
'div', props,
...elements
https://riptutorial.com/ 110
);
}
static title() {
return '';
}
static css() {
return '';
}
}
Tab
render() {
var props = Object.assign({
className: this.props.active ? 'active' : ''
}, this.props);
return React.createElement(
'li', props,
React.createElement(
'span', props,
props.panelClass.title()
)
);
}
}
panelClass property of Tab instance must contain class of panel used for description.
PanelGroup
https://riptutorial.com/ 111
this.setState({
panels: props.panels
});
}
render() {
this.tabSet = [];
this.panelSet = [];
for (let panelData of this.state.panels) {
var tabIsActive = this.state.activeTab ==
panelData.name; this.tabSet.push(React.createElement(
Tab, {
name: panelData.name,
active: tabIsActive,
panelClass: panelData.class,
onMouseDown: () => this.openTab(panelData.name)
}
));
this.panelSet.push(React.createElement(
panelData.class, {
id: panelData.name,
active: tabIsActive,
ref: tabIsActive ? 'activePanel' : null
}
));
}
return React.createElement(
'div', { className: 'PanelGroup' },
React.createElement(
'nav', null,
React.createElement(
'ul', null,
...this.tabSet
)
),
...this.panelSet
);
}
openTab(name) {
this.setState({ activeTab: name });
this.findDOMNode(this.refs.activePanel).focus();
}
}
panelsproperty of PanelGroup instance must contain array with objects. Every object there declares
important data about panels:
Clarification
When tab is down, needed panel is getting class name active on DOM element (means that it
gonna be visible) and it's focused now.
https://riptutorial.com/ 112
Example view with `PanelGroup`s
render() {
return React.createElement(
'main', null,
React.createElement(
Pane, { id: 'common' },
React.createElement(
PanelGroup, {
panels: [
{
name: 'console',
panelClass: ConsolePanel
},
{
name: 'figures',
panelClass: FiguresPanel
}
],
activeTab: 'console'
}
)
),
React.createElement(
Pane, { id: 'side' },
React.createElement(
PanelGroup, {
panels: [
{
name: 'properties',
panelClass: PropertiesPanel
}
],
activeTab: 'properties'
}
)
)
);
}
}
static title() {
return 'Console';
}
}
https://riptutorial.com/ 113
class FiguresPanel extends Panel {
constructor(props) {
super(props);
}
static title() {
return 'Figures';
}
}
static title() {
return 'Properties';
}
}
Remarks
Flow | React
Examples
Using Flow to check prop types of stateless functional components
type Props = {
posts: Array<Article>,
dispatch: Function,
children: ReactElement
}
const AppContainer =
({ posts, dispatch, children }: Props) => (
<div className="main-app">
<Header {...{ posts, dispatch }} />
{children}
</div>
)
https://riptutorial.com/ 114
import React, { Component } from 'react';
type Props = {
posts: Array<Article>,
dispatch: Function,
children: ReactElement
}
render () {
// rest of the code goes here
}
}
Remarks
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. It's
more of a pattern rather than a formal framework, and you can start using Flux immediately
without a lot of new code.
Flux applications have three major parts: the dispatcher, the stores, and the views (React
components). These should not be confused with Model-View-Controller. Controllers do exist in a
Flux application, but they are controller-views — views often found at the top of the hierarchy that
retrieve data from the stores and pass this data down to their children. Additionally, action creators
— dispatcher helper methods — are used to support a semantic API that describes all changes
that are possible in the application. It can be useful to think of them as a fourth part of the Flux
update cycle.
Flux eschews MVC in favor of a unidirectional data flow. When a user interacts with a React view,
the view propagates an action through a central dispatcher, to the various stores that hold the
application's data and business logic, which updates all of the views that are affected. This works
especially well with React's declarative programming style, which allows the store to send updates
without specifying how to transition views between states.
Examples
Data Flow
https://riptutorial.com/ 115
This is outline of comprehensive Overview.
1. Action — simple object describing action type and other input data.
2. Dispatcher — single action receiver and callbacks controller. Imagine it is central hub of
your application.
3. Store — contains the application state and logic. It registers callback in dispatcher and emits
event to view when change to the data layer has occured.
https://riptutorial.com/ 116
4. View — React component that receives change event and data from store. It causes re-
rendering when something is changed.
As of Flux data flow, views may also create actions and pass them to dispatcher
for user interactions.
Reverted
To make it more clearer, we can start from the end.
• Different React components (views) get data from different stores about made changes.
Few components may be called controller-views, cause they provide the glue
code to get the data from the stores and to pass data down the chain of their
descendants. Controller-views represent any significant section of the page.
• Stores can be remarked as callbacks that compare action type and other input data for
business logic of your application.
• Actions are nothing than simple objects with required type property.
Formerly, you'll want to use constants for action types and helper methods
(called action creators).
Firstly, you have to import jquery library . We also need to import findDOmNode as we’re going to
manipulate the dom. And obviously we are importing React as well.
We are setting an arrow function ‘handleToggle’ that will fire when an icon will be clicked. We’re
just showing and hiding a div with a reference naming ‘toggle’ onClick over an icon.
handleToggle = () => {
const el = findDOMNode(this.refs.toggle);
$(el).slideToggle();
};
handleToggle = () => {
const el = findDOMNode(this.refs.toggle);
$(el).slideToggle();
};
https://riptutorial.com/ 120
render() {
return (
<div className=”long-desc”>
<ul className=”profile-info”>
<li>
<span className=”info-title”>User Name : </span> Shuvo Habib
</li>
</ul>
We are done! This is the way, how we can use jQuery in React component.
Actually you can use ReactJS's components in Typescript as in facebook's example. Just replace
'jsx' file's extension to 'tsx':
//helloMessage.tsx:
var HelloMessage = React.createClass({
render: function() {
return <div>Hello {this.props.name}</div>;
}
});
ReactDOM.render(<HelloMessage name="John" />, mountNode);
But in order to make full use of Typescript's main feature (static type checking) should be done
couple things:
//helloMessage.tsx:
class HelloMessage extends React.Component {
render() {
return <div>Hello {this.props.name}</div>;
}
}
ReactDOM.render(<HelloMessage name="John" />, mountNode);
interface IHelloMessageState {
//empty in our case
}
Now Typescript will display an error if the programmer forgets to pass props. Or if they added
props that are not defined in the interface.
https://riptutorial.com/ 120
Stateless React Components in Typescript
React components that are pure functions of their props and do not require any internal state can
be written as JavaScript functions instead of using the standard class syntax, as:
class GreeterProps {
name: string
}
Note that, the name React.SFC is an alias for React.StatelessComponent So, either can be used.
To use typescript with react in a node project, you must first have a project directory initialized with
npm. To initialize the directory with npm init
Facebook released its own package manager named Yarn, which can also be used to install
React. After installing Yarn you just need to run this command:
You can then use React in your project in exactly the same way as if you had installed React via
npm.
To compile your code using typescript, add/install type definition files using npm or yarn.
https://riptutorial.com/ 121
yarn add --dev @types/react @types/react-dom
To use JSX, a language mixing javascript with html/xml, you have to change the typescript
compiler configuration. In the project's typescript configuration file (usually named tsconfig.json),
you will need to add the JSX option as:
"compilerOptions": {
"jsx": "react"
},
That compiler option basically tells the typescript compiler to translate the JSX tags in code to
javascript function calls.
To avoid typescript compiler converting JSX to plain javascript function calls, use
"compilerOptions": {
"jsx": "preserve"
},
The simplest react component without a state and no properties can be written as:
That component, however, can't access this.props since typescript can't tell if it is a react
component. To access its props, use:
Even if the component doesn't have explicitly defined properties, it can now access props.children
since all components inherently have children.
Another similar good use of stateless and property-less components is in simple page templating.
The following is an examplinary simple Page component, assuming there are hypothetical Container
, NavTop and NavBottom components already in the project:
https://riptutorial.com/ 122
import * as React from 'react';
https://riptutorial.com/ 123