Module-03 FSD (BIS601) - Final
Module-03 FSD (BIS601) - Final
MERCY
Module-03
Introduction to MERN: MERN components, Server less Hello world. React
Components: Issue Tracker, React Classes, Composing Components, Passing Data
Using Properties, Passing Data Using Children, Dynamic Composition.
Any web application is built using multiple technologies. The combinations of the technologies is
called a stack.
LAMP stack-Linux, Apache, MySQL, PHP (all open source software)
In web development, Single Page Applications (SPAs) is a web application paradigm that avoids
fetching the contents of an entire web page from the server to display new contents. It instead uses
lightweight calls to the server to get some data or snippets and changes the web page.
When use Node.js separately it is difficult to connect database, for development need a framework.
Express is a minimal and flexible Node.js web application framework that provides a robust set of
features for web and mobile applications. Node.js is not a framework, it's a JavaScript runtime
environment that allows to execute JavaScript code outside of a web browser, enabling server-side
scripting and building scalable network applications.
1
FULL STACK DEVELOPMENT (BIS601) S.MERCY
MERN Components:
MERN is a full-stack JavaScript solution for developing web applications, meaning both the client-
side (React) and server-side (Node.js, Express) are written in JavaScript, simplifying the development
process. The rise of MERN is linked to the trend of building Single Page Applications (SPAs), where
data is dynamically loaded without reloading the entire page. React is a key part of this as it allows for
dynamic updates to the user interface. MongoDB and Express work together to handle data and server-
side logic.
The MERN stack is a popular collection of technologies used to build modern web applications. MERN
stands for:
1. MongoDB: A NoSQL document-oriented database that stores data in a flexible, JSON-like
format, making it ideal for applications that require scalable and flexible data storage. It has a
flexible schema and a JSON-based query language.
NoSQL stands for “non-relational”, it’s essentially not a conventional database where you have
tables with columns and rows and strict relationships among them.
Two attributes of NoSQL databases that differentiate them from the conventional.
first is their ability to horizontally scale by distributing the load over multiple servers.
Second NoSQL databases are not necessarily relational databases.( no need to think of
the object in terms of rows and columns of tables)
The unit of storage (comparable to a row) is a document, or an object, and multiple documents
are stored in collections (comparable to a table). Every document in a collection has a unique
identifier, using which it can be accessed. The identifier is indexed automatically.
MongoDB has the ability to index on deeply nested fields, which relational databases cannot
do. All documents in a collection need not have the same set of fields.
MongoDB’s language is JavaScript. For relational databases, had a query language called SQL.
For MongoDB, the query language is based on JSON. Create, search for, make changes, and
delete documents by specifying the operation in a JSON object.
2
FULL STACK DEVELOPMENT (BIS601) S.MERCY
o Manages API endpoints, sessions, cookies, authentication, and other web server-related
functionality.
o It acts as a middleware to interact with databases and the front-end efficiently.
3. React: This is the defining component of the MERN stack. It is an open-source JavaScript
library maintained by Facebook that can be used for creating views rendered in HTML. A
JavaScript library for building user interfaces. Unlike full-fledged frameworks like Angular,
React focuses on the "view" part of the MVC (Model-View-Controller) architecture. It allows
developers to create interactive and dynamic user interfaces by breaking them down into
reusable components.
Unlike AngularJS, React is not a framework. It is a library.
Companies that use React in production like Airbnb, Atlassian, Bitbucket, Disqus,
Walmart, etc.
React views are declarative. Don’t have to worry about managing the effect of changes in the view’s
state or the data. In other words, don’t worry about transitions or mutations in the DOM caused by
changes to the view’s state. Being declarative makes the views consistent, predictable, easier to
maintain, and simpler to understand. A React component declares how the view looks given the data.
Example: A new row has been inserted in a table, create DOM element and insert it using jQuery. In
React don’t do anything the React library figures out how the new view looks and renders that. When
things change, React builds a new virtual DOM based on the new truth (state) and compares it with the
old (before things changed) virtual DOM. React then computes the differences in the old and the
changed Virtual DOM, then applies these changes to the actual DOM.
Component-Based. The fundamental building block of React is a component that maintains its own
state and renders itself. In React, all is to build components. Then, put components together to make
another component that depicts a complete view or page. A component encapsulates the state of data
and the view, or how it is rendered. This makes writing and reasoning about the entire application
easier, by splitting it into components and focusing on one thing at a time. Components talk to each
other by sharing state information in the form of read-only properties to their child components and by
callbacks to their parent components. Components in React are very cohesive but the coupling with
one another is minimal.
No Templates. Many web application frameworks rely on templates to automate the task of creating
repetitive HTML or DOM elements.
4
FULL STACK DEVELOPMENT (BIS601) S.MERCY
React uses a full-featured programming language to construct repetitive or conditional DOM elements.
That language is none other than JavaScript. For example, want to construct a table, write a for(...) loop
in JavaScript or use the map() function of Array.
There is an intermediate language to represent a virtual DOM that is JSX (JavaScript XML) which is
very much like HTML. JSX is not a programming language, it is representational markup like HTML.
Isomorphic. React can be run on the server too. Isomorphic means the same code can run on the server
and the browser. This allows to create pages on the server when required. To run React code on the
server need Node.js that can run JavaScript.
Type: Frontend JavaScript library for building user interfaces.
Role: Renders dynamic and interactive UIs by breaking down the UI into reusable components.
Why React?
o Component-based structure allows for modular and maintainable code.
o Virtual DOM for optimized performance and minimal UI updates.
o React is declarative, meaning you describe what the UI should look like, and React takes
care of updates when data changes.
o It’s commonly used to build Single Page Applications (SPAs).
5
FULL STACK DEVELOPMENT (BIS601) S.MERCY
Therefore split the code into files or modules for the sake of better organization and load them using
require.
Node.js ships with a bunch of core modules compiled into the binary. These modules provide access
to the operating system elements such as the file system, networking, input/output, etc. They also
provide some utility functions that are commonly required by most programs.
Node.js and npm-npm is the default package manager for Node.js. Use npm to install third-party
libraries (packages) and manage dependencies between them. The npm registry (www.npmjs.com) is
a public repository of all modules published by people for the purpose of sharing.
Although npm started off as a repository for Node.js modules, it quickly transformed into a package
manager for delivering other JavaScript based modules, notably, those that can be used in the browser.
jQuery, the most popular client-side JavaScript library, is available as an npm module.
Node.js, on the other hand, has no threads. It relies on callbacks which let to know that a pending task
is completed. Node.js achieves multi-tasking using an event loop. This is nothing but a queue of events
that need to be processed, and callbacks to be run on those events.
Type: JavaScript runtime environment.
Role: Runs JavaScript code server-side, enabling to use JavaScript for both front-end and back-
end code.
Why Node.js?
o Asynchronous, event-driven, non-blocking input/output model making it well-suited for
real-time applications and high-performance tasks.
o Runs JavaScript code outside the browser, which helps unify development for both
front-end and back-end teams.
React-Router: React gives only the View rendering capability and helps manage interactions in a
single component. When it comes to transitioning between different views of the component and
keeping the browser URL in sync with the current state of the view, need something more. This
capability of managing URLs and history is called routing.
6
FULL STACK DEVELOPMENT (BIS601) S.MERCY
It is similar to server-side routing that Express does: a URL is parsed and based on its components, a
piece of code is associated with the URL.
React-Router not only does this, but also manages the browser’s Back button functionality so it can
transition between what seem as pages without loading the entire page from the server. React-Router
is a very easy-to-use library that manages this.
React-Bootstrap: Bootstrap, the most popular CSS framework, has been adapted to React and the
project is called React Bootstrap. This library not only gives most of the Bootstrap functionality, but
the components and widgets provided by this library also give a wealth of information on how to design
the own widgets and components.
Webpack: Webpack not just to modularize and build the client-side code into a bundle to deliver to
the browser, but also to “compile” some code.
• Mongoose: This library adds a level of abstraction over the MongoDB database layer and
lets the developer see objects as such.
• Jest: This is a testing library that can be used to test React applications easily
MERN Components
Node.js, Express, MongoDB, React, React Router, React Bootstrap, Webpack.
Best part about MERN is that there is a single language used everywhere. Use JavaScript for
client-side code as well as server-side code.
Isomorphic
When React-based code runs on the browser, it gets data from the server and constructs the page
(DOM) in the browser. This is the SPA way of rendering the UI. To generate the same page in the
server for search engine bots, the same React-based code can be used to get the data from an API server
and construct the page (this time, as an HTML) and stream that back to the client. This is called server-
7
FULL STACK DEVELOPMENT (BIS601) S.MERCY
side rendering (SSR). The figure compares these two modes of operation.
Same language is used to run the UI construction code in the server and the browser so called the term
isomorphic.
This figure shows the comparison of the SPA way of doing things and server–side rendering using
React.
The first is the React core module, the one that is responsible for dealing with React
components, their state manipulation, etc.
The second is the ReactDOM module, which deals with converting React components
to a DOM that a browser can understand.
These two libraries can be found in unpkg, a Content Delivery Network (CDN) that makes
all open-source JavaScript libraries available online.
In the <head> section, include React and ReactDOM using <script> tags pointing to Content
Delivery Network (CDN) URLs:
o React: Manages the creation and handling of components and their states.
o ReactDOM: Converts React components into actual DOM elements that can be
rendered in the browser.
...
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
...
3. Creating the React Element:
o Inside the <body>, create a div element with an id="content", which will later hold the
React components.
...
<div id="content"></div>
...
o Using React.createElement(), define a React element. In this case, a div with a title
attribute containing an h1 heading with the text "Hello World!".
9
FULL STACK DEVELOPMENT (BIS601) S.MERCY
The function takes in as arguments the element that needs to be rendered and the DOM
element that it needs to be placed under.
5. Result:
When opened in a modern browser, this file will display the message "Hello World!" inside a
div element.
To create the React element, the createElement() function of the React module needs to be called.
10
FULL STACK DEVELOPMENT (BIS601) S.MERCY
Each of these React elements needs to be transferred to the real DOM for the user interface to be
constructed on screen. To do this, a series of document.createElement() calls needs to be made
corresponding to each of the React elements. The ReactDOM does this when the ReactDOM.render()
function is called.
11
FULL STACK DEVELOPMENT (BIS601) S.MERCY
React Components:
React components can be composed using other components and basic HTML elements; they can
respond to user input, change state, interact with other components, and much more.
Issue Tracker: GitHub Issues or Jira. These applications helps to create a bunch of issues or bugs,
assign them to people, and track their statuses. These are essentially CRUD applications (Create, Read,
Update, and Delete a record in a database) that manage a list of objects or entities.
In the case of the Issue Tracker, it only deal with a single object or record, because that’s good enough
to depict the pattern.
Issue Tracker: a list of issues.
The user should be able to add new issues, by supplying the initial values of the issue’s fields.
The user should be able to edit and update an issue by changing its field values.
The user should be able delete an issue.
An issue should have following attributes:
• A title that summarizes the issue (freeform long text)
• An owner to whom the issue is assigned (freeform short text)
• A status indicator (a list of possible status values)
• Creation date (a date, automatically assigned)
12
FULL STACK DEVELOPMENT (BIS601) S.MERCY
React Classes
React classes are used to create real components.
These classes can then be reused within other components, handle events, and so much more.
React classes are created by extending React.Component, the base class from which all custom classes
must be derived. Within the class definition, at the minimum, a render() method is needed. This method
is what React calls when it needs to display the component in the UI.
render() is one that must be present, otherwise the component will have no screen presence. The
render() function is supposed to return an element (which can be either a native HTML element or an
instance of another React component).
Example:
change the Hello World example from a simple element to use a React class called HelloWorld,
extended from React.Component:
...
class HelloWorld extends React.Component {
...
}
...
Now, within this class, a render() method is needed, which should return an element.
...
render() {
return (
<div title="Outer div">
<h1>{message}</h1>
</div>
);
...
Now move all the code for message construction to within the render() function so that it remains
encapsulated within the scope where it is needed rather than polluting the global namespace.
13
FULL STACK DEVELOPMENT (BIS601) S.MERCY
...
render() {
const continents = ['Africa','America','Asia','Australia','Europe'];
const helloContinents = Array.from(continents, c => `Hello ${c}!`);
const message = helloContinents.join(' ');
return (
...
);
...
In React, class components are a fundamental way to create reusable UI elements. These classes are
built by extending React.Component, which provides essential functionality such as state management
and lifecycle methods.
14
FULL STACK DEVELOPMENT (BIS601) S.MERCY
HelloWorld and div are actually React component classes, whereas <HelloWorld /> and <div /> are
tangible components or instances of the component class. Needless to say, there is only one HelloWorld
class, but many HelloWorld components can be instantiated based on this class.
15
FULL STACK DEVELOPMENT (BIS601) S.MERCY
Composing Components
React allows building UI using both built-in and user-defined components. Component composition
helps break the UI into smaller, independent pieces, making it easier to develop, understand, and
maintain. A component takes inputs (called properties) and its output is the rendered UI of the
component.
Things to remember when composing components:
• Larger components should be split into fine-grained components when there is a logical
separation possible between the fine-grained components.
• When there is an opportunity for reuse, components can be built which take in different inputs
from different callers.
• React’s philosophy prefers component composition in preference to inheritance (eg. a
specialization of an existing component can be done by passing properties to the generic component
rather than inheriting from it).
• In general, remember to keep coupling between components to a minimum. (coupling is where
one component needs to know about the details of another component, including parameters or
properties passed between them).
16
FULL STACK DEVELOPMENT (BIS601) S.MERCY
...
render() {
return (
);
...
...
...
<div>This is a placeholder for a table of issues.</div>
...
class IssueAdd extends React.Component {
...
...
To put these together, remove the Hello World class and add a class called IssueList.
...
...
17
FULL STACK DEVELOPMENT (BIS601) S.MERCY
Now add a render() method. Within this method, add an instance of each of the new placeholder classes
separated by a <hr> or horizontal line.
The return of render() has to be a single element, these elements have to be enclosed within a <div> or
a React Fragment component. The Fragment component is like an enclosing <div> but it has no effect
on the DOM.
...
render() {
return (
<React.Fragment>
<h1>Issue Tracker</h1>
<IssueFilter />
<hr />
<IssueTable />
<hr />
<IssueAdd />
</React.Fragment>
);
...
Finally, instead of instantiating a HelloWorld class, instantiate the IssueList class, which will
place under the contents div.
...
const element = <HelloWorld />;
const element = <IssueList />;
...
18
FULL STACK DEVELOPMENT (BIS601) S.MERCY
Listing 3-2. App.jsx: Composing Components (shows the new contents of the App.jsx file with all the
component classes.)
render() {
return (
);
render() {
return (
);
render() {
return (
);
19
FULL STACK DEVELOPMENT (BIS601) S.MERCY
render() {
return (
<React.Fragment>
<h1>Issue Tracker</h1>
<IssueFilter />
<hr />
<IssueTable />
<hr />
<IssueAdd />
</React.Fragment>
);
ReactDOM.render(element, document.getElementById('contents'));
Composing components without any variables is not so interesting. It should be possible to pass
different input data from a parent component to a child component and make it render differently on
different instances. In the Issue Tracker application, one such component that can be instantiated with
different inputs is a table-row showing an individual issue. Depending on the inputs (an issue), the row
can display different data.
The above figure shows the IssueList UI hierarchy with issue rows.
Create a component called IssueRow, and then use this multiple times within IssueTable, passing in different
data to show different issues:
...
render() {
return (
<table>
<thead>
<tr>
<th>ID</th>
21
FULL STACK DEVELOPMENT (BIS601) S.MERCY
<th>Title</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
);
...
The easiest way to pass data to child components is using an attribute when instantiating a component.
Any custom attribute can also be passed in a similar manner like this from IssueTable:
Used the name issue_title rather than simply title to avoid a confusion between this custom attribute
and the HTML title attribute. Now, within the render() method of the child, the attribute’s value can be
accessed via a special object variable called props, which is available via the this accessor. For
example, this is how the value of issue_title can be displayed within a cell in the IssueRow component:
22
FULL STACK DEVELOPMENT (BIS601) S.MERCY
It passed across a simple string. Other data types and even JavaScript objects can be passed this way.
Any JavaScript expression can be passed along, by using curly braces ({}) instead of quotes, because
the curly braces switches into the JavaScript world.
So, pass the issue’s title (as a string), its ID (as a number), and the row style (as an object) from
IssueTable to IssueRow. Within the IssueRow class, use these passed-in properties to display the ID
and title and set the style of the row, by accessing these properties through this.props
23
FULL STACK DEVELOPMENT (BIS601) S.MERCY
Give the rows a silver border of one pixel and some padding, say four pixels. The style object that
would encapsulate this specification would be as follows:
This can be passed on to the IssueRow component using rowStyle={rowStyle} when instantiating it.
This, and the other variables, can be passed to IssueRow while instantiating it like this:
Note that not using string-like quotes for the Issue ID since it is a number or for rowStyle since it
is an object. Instead use the curly braces, which makes it a JavaScript expression.
Construct the IssueTable component with a header row and two columns (ID and title), and two hard-
coded IssueRow components.
Specify an inline style for the table to indicate a collapsed border and use the same rowStyle variable
to specify the header row styles, to make it look uniform.
Listing 3-4 shows the modified IssueTable component class
24
FULL STACK DEVELOPMENT (BIS601) S.MERCY
25
FULL STACK DEVELOPMENT (BIS601) S.MERCY
When the parent React component renders, the children are not automatically under it because the
structure of the parent React component needs to determine where exactly the children will appear. So,
React lets the parent component access the children element using this.props.children and lets the parent
component determine where it needs to be displayed. This works great when one needs to wrap other
components within a parent component.
...
class BorderWrap extends React.Component {
render() {
return (
<div style={borderedStyle}>
{this.props.children}
</div>
);
}
...
Then, during the rendering, any component could be wrapped with a padded border like this:
...
<BorderWrap>
<ExampleComponent />
</BorderWrap>
...
26
FULL STACK DEVELOPMENT (BIS601) S.MERCY
Thus, instead of passing the issue title as a property to IssueRow, this technique could be used to embed
it as the child contents of <IssueRow> like this:
Now, within the render() method of IssueRow, instead of referring to this.props.issue_title, it will need
to be referred to as this.props.children, like this:
Let’s modify the application to use this method of passing data from IssueTable to IssueRow. Let’s also
pass in a nested title element as children, one that is a <div> and includes an emphasized piece of text.
This change is shown in Listing 3-5
...
...
return (
<tr>
<td style={style}>{this.props.issue_id}</td>
<td style={style}>{this.props.issue_title}</td>
<td style={style}>{this.props.children}</td>
</tr>
);
...
27
FULL STACK DEVELOPMENT (BIS601) S.MERCY
28
FULL STACK DEVELOPMENT (BIS601) S.MERCY
Dynamic Composition
It will replace the hard-coded set of Issue Row components with a programmatically generated
set of components from an array of issues.
Use a simple in-memory JavaScript array to store a list of issues.
Now expand the scope of the issue from just an ID and a title to include as many fields of an
issue.
It has just two issues. The field due is left undefined in the first record, to ensure that it handle
the fact that this is an optional field.
The in-memory array declared globally at the beginning of the file App.jsx.
{
id: 2, status: 'Assigned', owner: 'Eddie', effort: 14,
created: new Date('2018-08-16'), due: new Date('2018-08-30'),
title: 'Missing bottom border on panel',
},
];
Now modify the IssueTable class to use this array of issues rather than the hard-coded list.
29
FULL STACK DEVELOPMENT (BIS601) S.MERCY
Within the IssueTable class’ render() method, let’s iterate over the array of issues and generate an array
of IssueRows from it. The map() method of Array can map an issue object to an IssueRow instance.
Also, instead of passing each field as a property, pass the issue object itself because there are many
fields as part of the object.
To use a for loop instead of the map() method, can’t do that within the JSX, as JSX is not really a
templating language. It only can allow JavaScript expressions within the curly braces.
Have to create a variable in the render() method and use that in the JSX. Let’s create that variable for
the set of issue rows like that anyway for readability:
...
const issueRows = issues.map(issue => <IssueRow rowStyle={rowStyle} issue={issue}/>);
...
Now, replace the two hard-coded issue components inside IssueTable with this variable within
the <tbody> element like this:
...
...
<tbody>
{issueRows}
</tbody>
…
30
FULL STACK DEVELOPMENT (BIS601) S.MERCY
In other frameworks and templating languages, creating multiple elements using a template would have
required a special for loop construct (e.g., ng-repeat in AngularJS) within that templating language.
The header row in the IssueTable class will now need to have one column for each of the issue fields,
so let’s do that as well.
But by now, specifying the style for each cell is becoming tedious, so let’s create a class for the table,
name it table-bordered, and use CSS to style the table and each table-cell instead. This style will need
to be part of index.html, and Listing 3-7 shows the changes to that file.
Now, remove rowStyle from all the table-cells and table-headers. One last thing that needs to be done
is to identify each instance of IssueRow with an attribute called key. The value of this key can be
anything, but it has to uniquely identify a row. React needs this key so that it can optimize the
calculation of differences when things change, for example, when a new row is inserted. Use the ID of
the issue as the key, as it uniquely identifies the row.
The final IssueTable class with a dynamically generated set of IssueRow components and the modified
header is shown in Listing 3-8.
31
FULL STACK DEVELOPMENT (BIS601) S.MERCY
The changes in IssueRow are quite simple. The inline styles have to be removed, and a few more
columns need to be added, one for each of the added fields. Since React does not automatically call
toString() on objects that are to be displayed, the dates have to be explicitly converted to strings. The
toString() method results in a long string, so let’s use toDateString() instead. Since the field due is
optional, need to also check for its presence before calling toDateString() on it. An easy way to do this
is to use the ternary ? - : operator in an expression like this:
...
issue.due ? issue.due.toDateString() : ''
...
32
FULL STACK DEVELOPMENT (BIS601) S.MERCY
The above figure shows, Issue Rows constructed programmatically from an array.
33