FULLSTACK DEVLOPMENT MODULE-4
FULL SATACK DEVELOPMENT
MODULE-4
REACT STATE, EXPRESS
React State(Class Components):
• State in ReactJS refers to an object that stores a component’s dynamic data and determines how the component
behaves.
• Whenever state changes, react re-renders the component to reflect the updated data.
• It is an instance of the React Component Class that can be defined as an object of a set of observable properties
that control the behavior of the component.
• The state essentially holds the data, something that can change, as opposed to the immutable properties in the form
of props.
Initial State:
• The state of a component is captured in a variable called this.state in the component’s class.
• which should be an object consisting of one or more key-value pairs.
• where each key is a state variable name and the value is the current value of that variable.
• We can create a state object within the constructor of the class component.
• Creating a state is essential to building dynamic and interactive components.
MANJUNATH J P,ASST.PROF,ISE,VEMANA IT 1
FULLSTACK DEVLOPMENT MODULE-4
Example-1: Initial &Using State (FileName:Index.js)
Async State Initialization:
• async state initialization refers to the practice of setting the initial state of a component asynchronously, often by
fetching data or performing an asynchronous operation during the component's lifecycle.
Very important steps:
• Step-1:State Initialization in the Constructor
• Step-2: Modifying State with setState
• Step-3:Why Is an Async Call Needed for Fetching Data?
• Step-4:Simulating an API Call with setTimeout()
• Step-5:Why Not Call loadData() in the Constructor?
• Step-6:Fetching Data in componentDidMount()
• React provides many other methods called lifecycle methods
1. componentDidMount():
2. componentDidUpdate()
3. componentWillUnmount()
4. shouldComponentUpdate()
componentDidMount():
MANJUNATH J P,ASST.PROF,ISE,VEMANA IT 2
FULLSTACK DEVLOPMENT MODULE-4
• This method is called as soon as the component’s representation has been converted and inserted into the
DOM.
• A setState() can be called within this method.
componentDidUpdate():
• This method is invoked immediately after an update occurs, but it is not called for the initial render.
• The method is also supplied the previous props and previous state as arguments.
componentWillUnmount():
• This method is useful for cleanup such as cancelling timers and pending network requests.
shouldComponentUpdate():
• This method can be used to optimize and prevent a rerender in case there is a change in the props or state
that really doesn’t affect the output or the view.
EXAMPLE:
Updating State:
• Updating State refers to changing or modifying the state in an application, which is a fundamental
concept in programming, particularly in frameworks like React or state management libraries like Redux.
• The state holds the data that determines the behavior of the application and the UI.
Using State in React:
• we should define the State in the constructor of the component’s class.
• React provides its own method setState().
• setState() method takes a single parameter and expects an object which should contain the set of values to
be updated.
Many developers may miswrite the code as below:
MANJUNATH J P,ASST.PROF,ISE,VEMANA IT 3
FULLSTACK DEVLOPMENT MODULE-4
Correct Method to Update State:
• let’s make a minor change to the state rather than set a completely new value to it.
• setting this.state.issues to a new value or modifying its elements is not allowed.
• this.setState() may cause the changes that are done directly to the state variable
• this.setState() may cause the changes that are done directly to the state variable to be
overwritten.
MANJUNATH J P,ASST.PROF,ISE,VEMANA IT 4
FULLSTACK DEVLOPMENT MODULE-4
Example-1:
(Or)
MANJUNATH J P,ASST.PROF,ISE,VEMANA IT 5
FULLSTACK DEVLOPMENT MODULE-4
Example 2:
Output:
Lifting State Up:
• Lifting state up is a concept in React where you move the state to a common ancestor component when multiple
components need to share state.
• Instead of maintaining the state in individual components, you "lift" it to the nearest common parent and pass it
down as props to the child components that need it.
• There is no straightforward way to communicate between siblings in React.
• Only parents can pass information down to children.
• React automatically propagates any changes to child components that depend on the parent component’s state. Further, we
did not have to write any code for inserting a row into the DOM. React calculated the changes to the virtual DOM and
inserted a new row.
Why Do We Lift State Up in React?
• React is built around the idea of components and unidirectional data flow, meaning data flows down from
parent to child through props.
• However, sometimes two or more sibling components need to share the same state. If each component
manages its own version of the state, inconsistencies can arise.
MANJUNATH J P,ASST.PROF,ISE,VEMANA IT 6
FULLSTACK DEVLOPMENT MODULE-4
Example-1:
MANJUNATH J P,ASST.PROF,ISE,VEMANA IT 7
FULLSTACK DEVLOPMENT MODULE-4
Example -2:
File name -App.js:
MANJUNATH J P,ASST.PROF,ISE,VEMANA IT 8
FULLSTACK DEVLOPMENT MODULE-4
Event Handling:
React provides a way to handle user input, button clicks, form submissions, and other DOM events, and allows
you to update the component's state in response.
Basic Steps for Event Handling in React
1. Event Binding: React’s event handling system is similar to handling events in DOM, but with slight
differences.
2. Updating State: State is updated using this.setState() in class components or useState() in functional
components.
3. Passing Events: Event handlers are passed as props to child components, and they can trigger state
updates in the parent component.
MANJUNATH J P,ASST.PROF,ISE,VEMANA IT 9
FULLSTACK DEVLOPMENT MODULE-4
Example :
(Or)
MANJUNATH J P,ASST.PROF,ISE,VEMANA IT 10
FULLSTACK DEVLOPMENT MODULE-4
Stateless Components (functional component):
• Stateless components, also called functional components, are components that only receive
props and render UI without maintaining any internal state.
• A functional component accepts props as an argument and returns a React element.
• Functional components are stateless components as they simply accept data and display them in some form,
that they are mainly responsible for rendering UI.
If a component does not depend on props, it can be written as a simple function whose name is the component
name.
Why use ReactJS Functional Components
ReactJS functional components offer several benefits over class components, including:
• Simplicity: Functional components are simpler and easier to read than class components, making them
ideal for small to medium-sized projects.
• Performance: Functional components are faster than class components because they don’t use the this
keyword, which can slow down rendering.
• Testability: Functional components are easier to test because they are stateless and don’t rely on lifecycle
methods.
• Reusability: Functional components can be reused across multiple projects, making them a great choice
for building component libraries.
Example-1: output:
Example-2
MANJUNATH J P,ASST.PROF,ISE,VEMANA IT 11
FULLSTACK DEVLOPMENT MODULE-4
MANJUNATH J P,ASST.PROF,ISE,VEMANA IT 12
FULLSTACK DEVLOPMENT MODULE-4
Example: Converting Class Components to Stateless Components Before
(Class Component)
class IssueRow extends React.Component {
render() {
const issue = this.props.issue;
return (
<tr>
<td>{issue.id}</td>
<td>{issue.status}</td>
<td>{issue.owner}</td>
<td>{issue.created.toDateString()}</td>
<td>{issue.effort}</td>
<td>{issue.due ? issue.due.toDateString() : ''}</td>
<td>{issue.title}</td>
</tr>
);
}
}
After (Stateless Functional Component)
const IssueRow = ({ issue }) => (
<tr>
<td>{issue.id}</td>
<td>{issue.status}</td>
<td>{issue.owner}</td>
<td>{issue.created.toDateString()}</td>
<td>{issue.effort}</td>
<td>{issue.due ? issue.due.toDateString() : ''}</td>
<td>{issue.title}</td>
</tr>
State vs. Props:
MANJUNATH J P,ASST.PROF,ISE,VEMANA IT 13
FULLSTACK DEVLOPMENT MODULE-4
Component Hierarchy:
• Split the application into components and subcomponents.
• Typically, this will reflect the data model itself. For example, in the Issue Tracker, the issues
array was represented by the IssueTable component, and each issue was represented by the
IssueRow component.
• Decide on the granularity just as you would for splitting functions and objects. The
component should be self-contained with minimal and logical interfaces to the parent.
• If you find it doing too many things, just like in functions, it should probably be split into
multiple components, so that it follows the Single Responsibility principle (that is, every
component should be responsible for one and only one thing).
• If you are passing in too many props to a component, it is an indication that either the
component needs to be split, or it need not exist: the parent itself could do the job.
Communication:
• Communication between components depends on the direction. Parents communicate to
children via props; when state changes, the props automatically change.
• Children communicate to parents via callbacks. Siblings and cousins can’t communicate with
each other, so if there is a need, the information has to go up the hierarchy and then back down.
• This is called lifting the state up. This is what we did when we dealt with adding a new issue.
The IssueAdd component had to insert a row in IssueTable.
• It was achieved by keeping the state in the least common ancestor, IssueList. The addition was
initiated by IssueAdd and a new array element added in IssueList’s state via a callback.
• The result was seen in IssueTable by passing the issues array down as props from IssueList.
• If there is a need to know the state of a child in a parent, you’re probably doing it wrong.
• Although React does offer a way using refs, you shouldn’t feel the need if you follow the one-
way data flow strictly: state flows as props into children, events cause state changes, which flows
back as props.
MANJUNATH J P,ASST.PROF,ISE,VEMANA IT 14
FULLSTACK DEVLOPMENT MODULE-4
Stateless Components
• In a well-designed application, most components would be stateless functions of
their properties. All states would be captured in a few components at the top of
the hierarchy, from where the props of all the descendants are derived.
• We did just that with the IssueList, where we kept the state. We converted all
descendent components to stateless components, relying only on props passed down
the hierarchy to render themselves.
• We kept the state in IssueList because that was the least common
component above all the descendants that depended on that state.
• Sometimes, you may find that there is no logical common ancestor. In such cases, you
may have to invent a new component just to hold the state, even though visually the
component has nothing.
Express and GraphQL:
• Express is a small framework that sits on top of Node.js’s web server functionality to simplify its
APIs and add helpful new features.
• It makes it easier to organize your application’s functionality with middle ware and routing; it
adds helpful utilities to Node.js’s HTTP objects;it facilitates the rendering of dynamic HTTP
objects.
Some of the unique features of Express:
• Routing
• Middleware
• Error Handling
• Request & Response Object
• Body Parsing
1).Routing :
• Routing is the process of handling an HTTP request that defines which kind of response will be
sent to the client on which particular request.
• In Node JS, we have a module called http to create a server, where we create a server using
http.createServer and pass a callback function to http.createServer.
2).Middleware:
• Middlewares are the middle processes that execute between processes.
• In terms of web development, when we store passwords in a database using a server, we use
middleware to encrypt our passwords to make them secure.
• But Node JS does not contain any middleware by default, but we can create our own custom
middleware in it.
3).Error Handling:
• Error handling is used to ensure the smooth running of your software or program in case of
any undetected issue in your software.
• in Express JS, it is much easier to handle errors because there are multiple ways to handle
errors, like asynchronous handling, global error handling, etc.
4).Request & Response Object:
• Request and Response means what is requested by the client side and, in exchange for that
request, what data is sent to the client side from the server side in terms of response.
Mr.MANJUNATH J P,Asst.Prof,ISE,Vemana IT 15
FULLSTACK DEVLOPMENT MODULE-4
Request Object
A few important and useful request properties and request methods are listed here:
• req.params: This is an object containing properties mapped to the named route parameters.
• req.query: This holds a parsed query string. It’s an object with keys as the query string
parameters and values as the query string values.
• req.header, req.get(header): The get method gives access to any header in the request. The
header property is an object with all headers stored as key-value pairs.
• req.path: This contains the path part of the URL, use this property to get the actual path that was
received in the request.
• req.url, req.originalURL: These properties contain the complete URL, originalURL will hold
the URL as it was received, before the modification.
• req.body: This contains the body of the request, valid for POST, PUT, and PATCH requests.
Response Object
• res.send(body): which responded with a string, If the body is an object or an array, it is
automatically converted to a JSON string with an appropriate content type.
• res.status(code): This sets the response status code. If not set, it is defaulted to 200 OK.
• res.json(object): This is the same as res.send(), except that this method forces conversion of the
parameter passed into a JSON.
• res.sendFile(path): This responds with the contents of the file at path. The content type of the
response is guessed using the extension of the file.
Body Parsing:
• Body parsing refers to parsing data sent from the client side to the server side. The client sent
data in the body of the request and sent the type of content in headers, so converting data
according to the content type is called body parsing.
REST API :
• REST API stands for REpresentational State Transfer API. It is a type of API (Application
Programming Interface) that allows communication between different systems over the internet.
• REST APIs work by sending requests and receiving responses, typically in JSON format,
between the client and server.
Resource Based:
• Resources are accessed based on a Uniform Resource Identifier (URI), also known as an
endpoint.
Mr.MANJUNATH J P,Asst.Prof,ISE,Vemana IT 16
FULLSTACK DEVLOPMENT MODULE-4
HTTP Methods as Actions:
To access and manipulate the resources, you use HTTP methods.
GraphQL:
• GraphQL is an open-source data query language for APIs and It is a server-side runtime for
executing the query. The server's GraphQL runtime takes care of executing the query and
ensuring that the right data is fetched and sent back.
• It is an alternative to REST, where clients make multiple requests to different endpoints to get
the data they require but in GraphQL clients can request exactly the data they need in a single
query.
Key Features of GraphQL
GraphQL has several features that set it apart from traditional REST APIs, offering developers a more
flexible and efficient way to manage data. Let's explore these features as follows:
1. Flexible Queries: Clients can request exactly the data they need, avoiding over-fetching and
under-fetching.
2. Strongly Typed: GraphQL schemas provide clear data structures and types, reducing runtime
errors.
3. Real-time Updates: GraphQL supports subscriptions for real-time data interactions.
4. Single Endpoint: Unlike REST, GraphQL typically uses a single endpoint for all data requests.
5. Introspection: Clients can explore the schema's capabilities through introspection queries.
6. Batching: Multiple queries can be sent in a single request to minimize network overhead.
7. Efficient for Mobile: GraphQL can be more efficient for mobile devices by reducing data
transfer.
8. Versioning: It eliminates the need for versioning in APIs, as changes can be made without
breaking existing clients.
Mr.MANJUNATH J P,Asst.Prof,ISE,Vemana IT 17
FULLSTACK DEVLOPMENT MODULE-4
Key Components of GraphQL:
. Schema
It defines the data types that can be queried and their relationships. GraphQl uses it's own language that
is Schema Definition Language (SDL) for writing the schema. It is human readable language and It does
not depends upon any specific language or framework. Schemas has two main types:
1. Queries (for retrieving data)
2. Mutations (for modifying data).
2. Types
GraphQL defines custom types to define the structure of data. There are two main types of Type:
• Scalar Types: It represent values like integers, strings, booleans, and floats.
• Object Types: It represent complex objects with fields. Fields can be scalars or other object
types. For example, A "User" object type with fields like "id", "name", and "email".
3. Queries
• It is used to retrieve data from a GraphQL server. It specify what type of data we want to retrieve
from fields of which types. It is similar to GET requests in REST APIs but allow to request
exactly the data we need. It is reducing over-fetching or under-fetching.
4. Mutations
• It is used to modify data on the server. It can be used for creating, updating, or deleting data.
Mutations are similar to POST, PUT, or DELETE requests in REST APIs.
The About API GraphQL Schema file:
• A GraphQL Schema serves as a blueprint for the API that defines what data can be queried from
the server, and what are the different types of that data. They define a contract of API between a
server and a client.
A GraphQL Schema is divided into basic components like below:
1. Types
• The types of fields that we can fetch or query on the server. It represents the different types
available in GraphQL that we can specify on the various fields to be queried upon using GraphQL
API.
Ex:
Mr.MANJUNATH J P,Asst.Prof,ISE,Vemana IT 18
FULLSTACK DEVLOPMENT MODULE-4
2. Fields:
• The different properties that can be queries upon in the API. They represent the different
properties available that can be queries upon the GraphQL API.
Example:
3. Queries:
• The type for the GraphQL Query API endpoint that gets called to fetch data from the server.
They are the entrypoints for fetching data from the server, and the Query type is defined at the
root of the GraphQL query.
Example:
4. Mutations:
• The type for the operations that define a change in the data. They are the root types for
the operations that modify the data on the server.
Example:
5. Subscriptions:
• The types for the operations that allows clients to get real-time updates from the server. They are
the root types for the operations from which the clients can receive real-time updates from the
server.
How to Write a GraphQL Schema?
Step 1: Creating a Node.js Server
• First, run the below command to initialise an npm project
• Now, install the dependencies for creating an Apollo Server using the below command
Step2: Defining Schema Type
Mr.MANJUNATH J P,Asst.Prof,ISE,Vemana IT 19
FULLSTACK DEVLOPMENT MODULE-4
• The schema definition of the about field that can be queried is written like this
Next, to indicate that this field needs a mandatory string input called message, we need to write
Let’s also name the variable that contains the schema typeDefs and define it as a string in
server.js:
Step 3: Creating a Resolver to Serve the Requests
we’ll have two properties named Query and Mutation in the resolver.
Let’s start defining this:
Let’s first define that message as a variable at the top of the file, we’ll need to use the let
keyword rather than const.
Now, all the function needs to do is return this variable
Mr.MANJUNATH J P,Asst.Prof,ISE,Vemana IT 20
FULLSTACK DEVLOPMENT MODULE-4
Example:
( Or )
Mr.MANJUNATH J P,Asst.Prof,ISE,Vemana IT 21
FULLSTACK DEVLOPMENT MODULE-4
Example-2:
Step-1: Creating a Node.js Server
run the below command to initialise an npm project
Now, install the dependencies for creating an Apollo Server using the below command –
Step-2: Defining Schema Type
Step-3: Creating a Resolver to Serve the Requests
Step-4: Creating and Starting the Apollo Server
Step 5: Integrating the Above Code Together in a Single File
Let's start our server by running the below command – node server.js
Output:
Mr.MANJUNATH J P,Asst.Prof,ISE,Vemana IT 22
FULLSTACK DEVLOPMENT MODULE-4
Lists (The List API) in GraphQL Schema:
• Lists are used to represent an array or collection of values.
• Lists are represented by enclosing the data type of the field name by using ' [ ] '
square brackets.
• Lists can hold different data types as required. It can consist of scalar types
like String, Int, Float, or Boolean, or it can contain another list.
• Lists in GraphQL can be of two types. They are nullable lists and non-nullable lists.
Syntax :nullable list Syntax :non-nullable list
Steps involved in creating a list:
Step 1: Define the Schema
Step 2: Implement Resolvers
Step 3: Test Your List in GraphiQL
Step 4: Execute the Below Query in the GraphiQL Interface
Example-1. schema.graphql: server.js:
Mr.MANJUNATH J P,Asst.Prof,ISE,Vemana IT 23
FULLSTACK DEVLOPMENT MODULE-4
Example-2: schema.graphql: server.js:
step-1: Define the Schema Step 2: Implement Resolvers
Step 3: Test Your List in GraphiQL
Step 4: Execute the Below Query in the GraphiQL
Interface
Output:
Mr.MANJUNATH J P,Asst.Prof,ISE,Vemana IT 24
FULLSTACK DEVLOPMENT MODULE-4
List API Integration:
Step 1: index.html: Changes for Including whatwg-fetch Polyfill
Step 2:App.jsx: Changes for Integrating the List API
Output:
Mr.MANJUNATH J P,Asst.Prof,ISE,Vemana IT 25
FULLSTACK DEVLOPMENT MODULE-4
Custom Scalar Types:
• GraphQL gives developers the power to define custom scalars, appropriate to their own
needs.
• here is also a great package called graphql-scalars ready for use that contains common
scalars that might be required.
Syntax :
Example :
• The scalar type has to be defined as such in the schema using the scalar keyword
followed by the name of the custom type.
schema.graphql: Changes in Schema for Scalar Date
A scalar type resolver needs to be an object of the class GraphQLScalarType, defined in the
package graphql-tools. Let’s first import this class in server.js:
The constructor of GraphQLScalarType takes an object with various properties. We can create
this resolver by calling new() on the type like this:
Two properties of the initializer—name and description—are used in introspection, so let’s set
them to the appropriate values:
Mr.MANJUNATH J P,Asst.Prof,ISE,Vemana IT 26
FULLSTACK DEVLOPMENT MODULE-4
server.js: Changes for Adding a Resolver for GraphQLDate
App.jsx: Changes for Receiving ISO Formatted Dates
Mr.MANJUNATH J P,Asst.Prof,ISE,Vemana IT 27
FULLSTACK DEVLOPMENT MODULE-4
The Create API:
• Instead of using the type keyword, we have to use the input keyword.
• Let’s first define this new input type called IssueInputs in the schema.
So, let’s add a description for IssueInputs as well as for the property status, saying it will be
defaulted to the value 'New' if not supplied:
schema.graphql: Changes for New Type IssueInputs and New Field issueAdd
Next, we need a resolver for issueAdd that takes in an IssueInput type and creates a new issue in
the in-memory database.
In the function, let’s set the ID and the created date as we did in the browser:
Mr.MANJUNATH J P,Asst.Prof,ISE,Vemana IT 28
FULLSTACK DEVLOPMENT MODULE-4
Further, let’s also default the status, if not supplied (since we have not declared it as a required
subfield) to the value 'New':
Finally, we can append the issue to the global variable issuesDB and return the issue object as is
This function now can be set as the resolver for the issueAdd field under Mutation:
The complete set of changes to server.js is shown below:
Mr.MANJUNATH J P,Asst.Prof,ISE,Vemana IT 29
FULLSTACK DEVLOPMENT MODULE-4
Create API Integration:
App.jsx:
Query Variables:
• GraphQL has a first-class way to factor dynamic values out of the query and pass them
as a separate dictionary.
• These values are called variables. This way of passing dynamic values is quite similar to
prepared statements in SQL queries.
• To use variables, we have to name the operation first. This is done by specifying a name
right after the query or mutation field specification.
Mr.MANJUNATH J P,Asst.Prof,ISE,Vemana IT 30
FULLSTACK DEVLOPMENT MODULE-4
App.jsx: Changes for Using Query Variables
Input Validations:
• GraphQL schema itself gives us an automatic way of doing this via enumeration types or
enums.
• An enum definition in the schema looks like this:
• JavaScript does not have enum types, these will be dealt with as strings, both in the client
as well as in the server.
• Let’s add this enum type for status called StatusType
• Now, we can replace the type String with StatusType in the Issue type:
• In the case of status, the default value is an enum, so it can be specified without the
quotes like this
Mr.MANJUNATH J P,Asst.Prof,ISE,Vemana IT 31
FULLSTACK DEVLOPMENT MODULE-4
schema.graphql: Changes for Using Enums and Default Values
• Let’s first create an array to hold the error messages of failed validations.
• When we find multiple validation failures, we’ll have one string for each validation failure
message in this array.
Next, let’s add a minimum length for the issue’s title. If that check fails, we’ll push a message
into the errors array.
Let’s also add a conditional mandatory validation,
Mr.MANJUNATH J P,Asst.Prof,ISE,Vemana IT 32
FULLSTACK DEVLOPMENT MODULE-4
Let’s implement this check in parseValue as well as parseLiteral:
We can use this option to print out the error on the console as well:
server.js: Programmatic Validations and Date Validations
Mr.MANJUNATH J P,Asst.Prof,ISE,Vemana IT 33
FULLSTACK DEVLOPMENT MODULE-4
Displaying Errors:
Mr.MANJUNATH J P,Asst.Prof,ISE,Vemana IT 34
FULLSTACK DEVLOPMENT MODULE-4
Output:
Mr.MANJUNATH J P,Asst.Prof,ISE,Vemana IT 35