ReactJS Notes
ReactJS Notes
(ECS)-III
Sem-VI
Type: DSE3-A
Course Title: Reacts
(Paper Code: Paper XVI)
Syllabus
Unit 1: Introduction to ReactJS [20]
Introduction, Workflow, Scope, Pros and Cons, Difference between JS and JSX, React Components overview,
Child Components, JSX expressions,
Building Blocks of ReactJS: JSX, Components, State and Props, Conditional Rendering, Why JSX, Advantages
of JSX, Expressions in JSX, Implementation of JSX, Creating a react component with jsx
Environment Setups: Node setup, How to use NPM, Npm and Setting Environment for ReactJS projects,
How to create package.json and purpose, IDE for ReactJS, ReactJS browser plugins overview. Components:
Types of components, Functional component vs Class Component, Converting Functional Components to
Class Components, Component Life Cycles and its different methods.
Unit 2: Conditional Rendering and List [10]
if-else Statement, logical & and operator, operators, Preventing Component from Rendering, Switch case
operator
List and Keys: react key prop, map function to iterate the List, References, use Refs, Create Refs, access
Refs, Event Binding types: Bind () method, Arrow function
Props and State: What is a state, use and role of the state, what are props, Props validation, Passing data
between multiple components, Managing Component State
Unit 3: Handling Events and Forms [10]
Lists of Form components, Setup Controlled and Uncontrolled form components, Control Input elements,
Form Submission and Validation, how to set default values on all formats of Input elements, Form
validations, writing Styles, Animations overview, Event, Event Binding, Event Handlers, Common React
Events, Key Events, Event Pooling, Synthetic Event.
Unit 4: Routing and State Management [20]
Introduction to React Router, History of Router, Single Page Application Overview, configure React
Router, Load the router library, Navigating between Routes, Route Parameters and Nested Routes,
Dynamic Routing, Nesting Routes, Invalid URL, Handle Conditional statement in JSX
State Management: Local State vs. Global State, State Lift-Up, Context API for Global State
Redux: Introduction to Redux, Redux Architecture- Actions, Reducers, and Store, Provider Component,
Dispatchers, View Controllers, Connecting React with Redux
Hooks: Introduction to Hooks, The useState hook, useEffect hook, Custom hook, useRef hook, useMemo
hook, The useContext hook, The useReducer hook, Another Hooks.
Introduction to ReactJS
ReactJS, a JavaScript library that was initially developed by Facebook for its internal use, has now become a
staple in the tech industry. It is widely adopted, from startups to big companies, and is used by over 40% of
web developers worldwide. In fact, it was the second most used web framework among developers
worldwide in 2023.
ReactJS is used in a wide range of applications. Some notable examples include Netflix's movie
recommendation system, Airbnb's search and booking system, and Uber Eats' food delivery tracking
system. These applications demonstrate the versatility and power of ReactJS in developing complex,
interactive, and user-friendly web applications.
ReactJS is primarily used to develop complex web applications. If you need to become more familiar
with It, this article will serve as an introduction. Additionally, we'll explore its applications, features, and a
ReactJS component to provide insight into its role in web development.
Need to launch a top-notch React application quickly? Our React development services have been trusted by
over 200 clients. Our efficient process gets your team set up in 48 hours, allowing you to focus on building
great software.
Role of ReactJS in Web Development World
Before we understand ReactJS's role in modern web development, let's first briefly understand the broader
picture of web development.
Let's break it down in plain English.
When we say web application development, we may refer to both the front and back end. The front end is
the part of the website that users interact with, while the back end handles the logic and data processing.
Several technologies exist today to power both ends of this spectrum.
React.js is used in front-end (client-side) development, specifically for a website's user interfaces. A popular
example of ReactJS development is Facebook's web app, which uses it to power several elements.
You might have observed the functionality of Facebook's web app, where tapping on elements doesn't
trigger a complete page reload. Instead, React.js efficiently updates the state of specific elements behind the
scenes.
ReactJS is used to develop dynamic web pages, which are web pages that can update their content or
appearance in response to user actions or changes in data. These pages offer users a smoother experience
compared to traditional pages that reload entirely with each interaction. ReactJS is particularly well-suited
for developing dynamic web pages, including single-page applications, mobile apps (with React Native),
complex user interfaces, real-time applications, and more.
If you are still trying to figure out after exploring the ReactJS features, don't worry. We'll also explore
various use cases of ReactJS to help you understand when it's an ideal choice and the types of applications
you can develop with it.
What is ReactJS?
React.js, often referred to simply as React, is an open-source JavaScript library for building user interfaces.
Its user-friendly nature allows for faster creation of web UIs, making it a go-to choice for world-renowned
brands, including Netflix, Salesforce, Instagram, Reddit, and countless organizations. With React, building
interactive web pages becomes a breeze.
As per the Stack Overflow 2023 Developer Survey, it is one of the most popular web frameworks.
Features of ReactJS
It follows a component-based architecture, a widely adopted approach for building modern applications.
Since modern applications require continuous upgrading, its component-based nature allows developers to
add new functionalities without rewriting the entire application.
Additionally, it provides an exclusive JSX language that promotes code maintainability and helps write
components more efficiently. Other key features of ReactJS include its ability to handle complex UI
updates, its support for server-side rendering, and its robust community and ecosystem. Let's look at some
key features of ReactJS that every developer should know.
1. JSX
JSX (JavaScript XML) is a JavaScript extension that allows you to write HTML-like code directly within
your React components. It's a powerful tool that enables you to keep your UI logic and data handling
together in a single place, enhancing code maintainability. While React allows you to write UI code without
JSX, using JSX can make your code more readable and promote a more organized and maintainable
codebase, making it a popular choice among React developers.
While React allows you to write UI code without JSX, you will find JSX to be a helpful tool as it allows you
to write the logic more readably and promotes a more organized and maintainable codebase.
2. Virtual DOM
DOM (Document Object Model) plays a crucial role in web application rendering. However, React takes a
different approach by utilizing a Virtual DOM.
React takes a unique approach to web application rendering by utilizing a Virtual DOM. In simple terms, the
Virtual DOM is a lightweight copy of the actual DOM, which is the structure of a web page. React creates
and maintains this virtual copy, allowing it to efficiently update only the necessary parts of the page when
the application's state changes. This approach minimizes browser work and improves rendering speed,
contributing to React's exceptional performance and responsiveness.
This creates a virtual copy because when your application state changes, React updates the virtual DOM
first. It then compares the virtual DOM with the real DOM to identify the minimal changes necessary. Only
the essential changes are applied to the actual DOM, minimizing browser work and improving rendering
speed.
React achieves lightning-fast rendering without directly manipulating the entire DOM, avoiding resource-
intensive operations. This optimization is a major reason React applications are renowned for their
exceptional performance and responsiveness. With React, you can be confident in the efficiency and speed
of your web applications.
3. Component-Based Architecture
React apps are built using reusable components. Each component represents a distinct UI part and
encapsulates its logic and representation. This component-based architecture makes building and
maintaining complex UIs easier, as each component can be developed and tested independently. It also
promotes code reusability, as components can be used in multiple parts of an application.
This approach is widely popular in the modern development. It lets you construct your UI by breaking
it down into reusable, independent components.
With JSX, you can efficiently construct components and create applications at a rapid pace. This is why it is
recommended that you write code in JSX in React to build complex UI and develop reusable components
efficiently.
4. Unidirectional Data Flow
In React, the data flows in a single direction, from top to bottom, i.e., from parent to child components
through properties. This unidirectional data flow is a key concept in ReactJS. It simplifies reasoning about
how changes in data will affect the UI and prevents unintended side effects. This makes it easier to
understand and debug React applications, and also contributes to the development of maintainable
applications.
This predictable data flow simplifies reasoning about how changes in data will affect the UI and prevent
unintended side effects. Furthermore, this unidirectional data flow is advantageous for developing
maintainable applications.
5. Components
React components are independent and reusable building blocks that define a part of a user interface. In
React, components can represent any part of your application's UI or functionality. They can range from
simple elements like buttons or colors to more complex components like forms, modals, navigation bars, and
entire sections of your application.
6. React Hooks
In React, there are two types of components: Functional components and class components. Functional
components enable writing code more straightforwardly and concisely. React Hooks, introduced in React
16.8, further enhance the functionality of functional components. They allow developers to manage state and
perform side effects within them, making it easier to reuse stateful logic between components.
Side effects are actions that occur outside the component's render function, such as data fetching,
subscriptions, or manually changing the DOM.
By utilizing Hooks, developers can achieve the functionality traditionally associated with class components
within functional components. We will delve deeper into functional components and class components later
in this article.
7. State
State in React is the internal data of a component. It encapsulates information that can change over time,
influencing the component's behavior and appearance. State is commonly used to handle dynamic data such
as user input, toggling UI elements, or managing component lifecycle events.
It is mutable, meaning it can be modified, triggering re-renders of the component to reflect the updated state.
8. Props
Props, short for properties, are immutable data passed from a parent component to a child component. They
serve as a means of communication between components, allowing data to be passed down the component
tree. This makes it easier to manage and update data in React applications.
Props facilitate the creation of flexible and modular components. They are commonly used to configure
child components, pass event handlers, or provide contextual information. Functional components,
especially with the widespread adoption of React Hooks, heavily rely on props to receive data and trigger
actions within the component.
Use of ReactJS
Conclusion
ReactJS is a versatile JavaScript library that can be used to build a wide variety of web applications. Its
focus on reusability, performance, and developer experience has made it one of the most popular choices for
front-end development today. With our React Development Services, you can create your ideal team
seamlessly. Whether you're looking to strengthen your current team or establish a proficient one from
scratch, we're here to realize your app vision.
Components Of ReactJS
Components in React are independent and reusable pieces that encapsulate UI(user interface) logic and
data.
There are two main types of React components:
Class components
These are traditional JavaScript classes that extend the `React.Component` class. Class components have a
render method that returns the UI for the component, as well as a number of lifecycle methods that allow
you to hook into different stages of the component's lifecycle (e.g., when the component is mounted,
updated, or unmounted).
Functional components
These are simply JavaScript functions that return JSX (JavaScript XML) code that describes the UI for the
component. Function components are generally simpler to write and use than class components, and they are
the preferred way to write React components in modern React applications.
Components can also be nested within other components, which allows you to build complex UIs by
composing smaller, reusable components. This hierarchical structure makes it easy to break down complex
UIs into manageable pieces.
Pros and Cons of ReactJS:
Pros of ReactJS
1. Component-Based Architecture:
o React follows a component-based architecture, where the UI is split into small, reusable
components. This makes it easier to manage and scale the application, as each component can
be developed, tested, and maintained independently.
o Components can also be reused across different parts of the application, reducing duplication
of code.
2. Declarative Syntax:
o React uses a declarative programming model, meaning you describe what you want the UI
to look like and React handles how to update the UI when the state changes.
o This leads to a more predictable and easier-to-maintain codebase.
3. Virtual DOM:
o React uses a Virtual DOM, which is a lightweight representation of the actual DOM. When
the state changes, React first updates the Virtual DOM and compares it with the previous
version (using a process called Reconciliation).
o After the diffing process, only the necessary updates are made to the actual DOM, improving
performance significantly, especially in complex applications.
4. Efficient and Fast:
o Due to the Virtual DOM and efficient re-rendering, React offers excellent performance, even
for large applications.
o React minimizes the number of direct manipulations of the real DOM, which can be slow.
5. Wide Ecosystem and Community Support:
o React has a large, active community and is widely used by developers. This results in a rich
ecosystem of libraries, tools, extensions, and third-party integrations.
o It's easier to find tutorials, guides, and solutions to common problems, making the learning
curve more manageable.
6. Unidirectional Data Flow:
o React has a one-way data flow, where data moves from parent to child components via
props. This makes it easier to understand how data changes flow through the app.
o This unidirectional data flow ensures better control over how data is managed and passed
around, especially when using state management libraries like Redux or React Context.
7. React Hooks:
o React hooks (introduced in React 16.8) allow for the use of state and lifecycle features in
functional components. This improves code readability and eliminates the need for class
components in many cases.
o Popular hooks like useState, useEffect, useContext, and useReducer enable developers to
write cleaner and more maintainable code.
8. Cross-Platform Development:
o With React Native, developers can use React to build mobile applications for both iOS and
Android, sharing most of the codebase between web and mobile apps.
o This can lead to a more unified codebase across different platforms, reducing development
time and costs.
9. SEO Friendly:
o While React is primarily client-side rendered, tools like Next.js (a framework built on top of
React) enable server-side rendering (SSR) and static site generation (SSG), making React
apps SEO-friendly.
o This allows React apps to rank better in search engines compared to traditional client-side
rendered apps.
10. JSX Syntax:
JSX (JavaScript XML) allows developers to write HTML-like code directly within JavaScript,
making it easier to visualize the structure of the component and simplifying the development
process.
JSX combines the power of JavaScript with the familiarity of HTML, making it easier to work with.
Cons of ReactJS
1. Learning Curve:
o While React's core concepts are simple, there is a learning curve when it comes to more
advanced topics like state management (Redux, Context API), component lifecycle, and
hooks.
o Developers may also need to learn additional tools and libraries (like Webpack, Babel, React
Router, etc.), which can be overwhelming for beginners.
2. SEO Challenges (for Client-Side Rendering):
o By default, React apps are rendered client-side, which can be problematic for search engine
optimization (SEO). Search engines may have difficulty indexing JavaScript-heavy content.
o While solutions like server-side rendering (SSR) or static site generation (SSG) exist (e.g.,
Next.js), they introduce complexity.
3. Frequent Updates and Changes:
o React has a fast-evolving ecosystem, with frequent updates and new features (like hooks)
being introduced. Keeping up with these changes can be time-consuming and may require
constant refactoring of codebases to stay up-to-date.
o Developers need to stay on top of new patterns and best practices to avoid using deprecated
features.
4. Requires Build Tools:
o React applications usually require build tools (e.g., Webpack, Babel) to bundle and transpile
code, which can be complex to configure.
o Even though tools like Create React App (CRA) simplify the setup, understanding how
these build tools work can be important for more advanced use cases.
5. Too Much JavaScript:
o React apps can often end up being heavily reliant on JavaScript, leading to large bundle
sizes. This can affect the initial loading time of your app, especially on slower networks.
o Optimizing bundle sizes requires techniques like code splitting and lazy loading, but this
adds additional complexity to the development process.
6. Overhead for Simple Projects:
o For small or simple projects, React may introduce unnecessary overhead. For basic websites
or apps that don't require a lot of interactivity, using React might be overkill compared to
traditional methods (e.g., simple HTML, CSS, and vanilla JavaScript).
o React’s component-based approach and the need for state management could be unnecessary
in such cases.
7. Boilerplate Code for State Management:
o Managing global state in large React applications can involve a lot of boilerplate code,
especially when using libraries like Redux or MobX.
o Setting up a global state with Redux, for example, requires actions, reducers, and connecting
components, which can be verbose and require additional setup for relatively simple state
management.
8. Performance Issues in Large Applications:
o Although React is optimized for performance with its Virtual DOM, in large, complex
applications with frequent updates or deeply nested components, performance issues can
arise.
o Developers may need to fine-tune performance using techniques like
shouldComponentUpdate, React.memo, or useMemo to avoid unnecessary re-renders.
9. JSX Can Be Confusing for Some Developers:
o JSX syntax combines HTML and JavaScript, which can be confusing for developers who are
used to working in pure HTML and JavaScript. The mix of both can lead to some readability
and maintainability concerns, especially when the code becomes large.
10. Not Truly MVC:
React doesn’t adhere to the traditional Model-View-Controller (MVC) design pattern. While React
is excellent for rendering the View, developers often have to manually implement a Model (state
management) and Controller (logic, actions).
This can make organizing large applications more challenging, requiring developers to find their own
patterns or use third-party libraries to manage application logic.
Summary
Pros:
Component-based architecture, reusable components
Virtual DOM for efficient rendering
Unidirectional data flow
Fast performance and scalability
Large community, ecosystem, and library support
Cross-platform development (React Native)
JSX syntax for readability
SEO improvements with SSR and SSG (Next.js)
Cons:
Learning curve, especially with advanced patterns (e.g., hooks, state management)
Client-side rendering SEO challenges (though solvable with SSR/SSG)
Frequent updates and changes to the ecosystem
Requires build tools like Webpack/Babel
Too much JavaScript and large bundle sizes
Overkill for small projects or static sites
Boilerplate code in state management (Redux, MobX)
Performance issues in complex apps (needs optimization)
JSX can be difficult to read for some developers
ReactJS is a powerful and flexible library for building modern web applications, but its suitability depends
on the project’s complexity, scale, and the developer’s experience.
ReactJS workflow
A ReactJS workflow typically refers to the set of practices, tools, and processes that developers use to
build, test, and deploy React applications. The workflow can vary depending on the scale of the project, the
team's preferences, and the tools they adopt, but here’s a general outline of the modern React development
workflow:
1. Setting Up the Project
Option 1: Create React App (CRA)
npx create-react-app my-app: A quick and easy way to create a new React project with a
sensible default configuration. It comes with React, Webpack, Babel, ESLint, and other tools pre-
configured.
Option 2: Custom Webpack/Babel Setup
For advanced users or more customized configurations, you might want to manually set up Webpack,
Babel, ESLint, etc. This gives you more control but requires more initial setup.
Option 3: Vite
A modern alternative to CRA, Vite offers faster build times and better developer experience with
support for hot module replacement (HMR) and a simpler configuration. To start with Vite, run:
bash
Copy code
npm create vite@latest my-app --template react
2. Development Environment Setup
Code Editor:
A code editor like VS Code is popular among React developers, thanks to its rich ecosystem of
extensions.
o Extensions: Prettier, ESLint, ES7 React/Redux/GraphQL/React-Native snippets, etc.
Version Control:
Git is the most widely used version control system. Set up Git repositories (on GitHub, GitLab, etc.)
to manage your codebase.
Make use of branches (main, dev, feature/xyz) and commit early and often.
Dependency Management:
npm or yarn to manage project dependencies.
It's common to install key packages for React apps such as:
o react-router-dom for routing
o axios or fetch for making API calls
o redux or react-query for state management (optional)
3. Component Design and State Management
Component-Based Architecture: React uses a component-based approach, where each part of the
UI is a separate reusable component.
State Management:
o Local State: Manage with React’s useState hook.
o Global State: Use Context API or libraries like Redux, Recoil, or Zustand for more
complex state management.
o Async Data Management: Use React Query or SWR for fetching and caching data from
APIs.
Folder Structure: You can organize your app’s components, hooks, utilities, and state in various ways. A
common structure might look like this:
4. Styling
CSS in JS:
React developers typically use CSS-in-JS libraries, such as:
o styled-components
o emotion
o @stitches/react
o These libraries allow for dynamic, scoped, and themeable styles within your components.
CSS Frameworks:
If you prefer traditional CSS, you might use a utility-first CSS framework like Tailwind CSS, or
something more component-based like Material-UI (MUI) or Ant Design.
Preprocessors:
For more advanced CSS, preprocessors like SASS or SCSS are often used, especially for larger
projects.
5. Development Tools
Hot Module Replacement (HMR): Most modern bundlers (Webpack, Vite) support HMR to
instantly apply code changes without needing a full page reload.
React DevTools: A browser extension that helps with debugging React applications, allowing you to
inspect the React component tree, state, and props.
ESLint & Prettier: For maintaining code quality and consistent formatting, integrate ESLint for
linting and Prettier for automatic code formatting. Many developers also use Husky to enforce pre-
commit hooks.
6. Testing
Jest: The most common testing framework for React applications. It can be used for unit tests,
integration tests, and mocking API calls.
React Testing Library: Works in conjunction with Jest for testing React components. It encourages
testing components from the user’s perspective by interacting with them as an end user would.
Cypress or Playwright: For end-to-end (E2E) testing. These tools allow you to test your app as a
whole by simulating real-world user interactions.
7. Build Process
Webpack / Vite: Both tools handle the bundling and optimization of your JavaScript, CSS, and
images. Vite is considered faster and more modern, while Webpack is more flexible and widely used.
Tree Shaking: Both tools remove unused code from the final bundle to reduce the size.
Code Splitting: Helps break down large bundles into smaller pieces that are loaded as needed
(dynamic imports).
Babel: Transpiles modern JavaScript and JSX code into a format supported by all browsers.
8. Code Quality & Collaboration
Prettier: Automatically formats your code, ensuring a consistent style throughout the project.
ESLint: Static analysis tool to find and fix problems in your JavaScript code, enforcing code style
rules.
Husky: Allows you to set up Git hooks, such as pre-commit hooks for linting and formatting before
pushing code to the repository.
9. Deployment
Static Site Generators: If you’re building a static site, you can use platforms like Vercel or Netlify
for instant deployment.
Docker: For more complex setups, Docker can be used to containerize your app and manage its
deployment with services like AWS or Azure.
CI/CD: Set up continuous integration and continuous deployment with tools like GitHub Actions,
GitLab CI, or CircleCI to automatically run tests, build the app, and deploy it to production.
10. Performance Optimization
Lazy Loading: Use React’s React.lazy and Suspense to load components only when needed,
improving performance by reducing initial bundle size.
Image Optimization: Tools like ImageOptim, or using next/image if using Next.js, can help
optimize images.
Code Splitting: Bundle your app in smaller chunks, so the browser only loads the necessary code
when needed.
Caching: Use service workers or caching strategies to improve app performance and offline
capabilities.
11. Monitoring & Analytics
Google Analytics or Mixpanel for tracking user behavior.
Sentry or LogRocket for error tracking and performance monitoring.
Performance Monitoring: React itself comes with tools to measure performance (e.g., React.memo,
useMemo, and useCallback for optimization). You can also use the built-in browser performance
tools.
Example React Workflow:
1. Initialize the project:
npx create-react-app my-app
2. Install dependencies:
npm install axios react-router-dom styled-components
3. Build components and pages in the src/components and src/pages directories.
4. Write tests:
Use Jest and React Testing Library to write unit tests and ensure component behavior.
5. Format code and lint:
Run npm run lint and npm run format before committing. Set up husky hooks.
6. Deploy:
Push the code to GitHub and deploy using Vercel or Netlify.
7. Monitor:
Use tools like Sentry to track errors and analyze performance.
This is a flexible and scalable workflow, and you can modify it according to the needs of your project, team,
or organization.
Steps to cerate reactApp without IDE
D:\>mkdir reactApp
D:\>cd reactApp
D:\reactApp>node -v
v22.12.0
D:\reactApp>npm -v
10.9.0
D:\reactApp\my-app>npm start
<div id="mydiv"></div>
<script type="text/babel">
function Hello()
{
return <h1>Hello World!</h1>;
}
const container = document.getElementById('mydiv');
const root = ReactDOM.createRoot(container);
root.render(<Hello />)
</script>
</body>
</html>
Scope in ReactJS
In ReactJS, scope generally refers to the context in which variables, functions, and components are
accessible within the application. React, like JavaScript, has its own rules regarding scope that are important
to understand when working with components, state, props, and events.
1. Scope of Variables
Global Scope: Any variable or function declared in the global context (outside of any function or
component) is accessible across your entire JavaScript application.
o Example:
// app.js
let globalVar = 'I am global';
function App()
{
console.log(globalVar); // Accessible here
return <div>{globalVar}</div>;
}
export default App;
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
Function Scope: Variables declared within a function are only accessible within that function.
o Example:
//app.js
function App() {
let localVar = 'I am local';
console.log(localVar); // Accessible here
return <div>{localVar}</div>;
}
console.log(localVar); // Error: localVar is not defined
export default App;
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
Block Scope (let & const): Variables declared using let or const inside a block (such as inside an if
or for loop) are only accessible within that block.
o Example:
//app.js
function App() {
if (true) {
const blockScopedVar = 'I am block scoped';
console.log(blockScopedVar); // Accessible here
}
console.log(blockScopedVar); // Error: blockScopedVar is not defined
}
export default App;
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
2. Component Scope
Local Component State: Each component in React has its own local state, which is scoped to that
specific component. You can use React hooks like useState to manage the state of a component.
o Example:
//app.js
import { useState } from 'react';
function Counter()
{
const [count, setCount] = useState(0);
return (
<div>
<p>{count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
export default Counter;
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import Counter from './App';
The count and setCount variables are scoped to the Counter component, so they can’t be accessed
outside of it.
Props: Props are values passed from a parent component to a child component. These are not
mutable by the child component and are scoped to the child component that receives them.
o Example:
//app.js
function Greeting(props) {
return <h1>Hello, {props.name}!</h1>;
}
function App() {
return <Greeting name="Sangola" />;
}
export default App;
//index,js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
const root =
ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
In the example above, props.name is scoped to the Greeting component and cannot be modified by it,
as props are read-only.
3. Event Handlers Scope
React events (like onClick, onChange, etc.) are often defined as methods or functions inside a component.
These event handlers need to be bound to the correct scope to access this (in class components) or
state/props (in functional components).
Class Components: In class components, event handlers usually need to be bound to the component
instance to maintain the correct this reference.
//app.js
import React from 'react';
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
this.increment = this.increment.bind(this); // Bind `this` to the method
}
increment() {
this.setState({ count: this.state.count + 1 });
}
render() {
return (
<div>
<p>{this.state.count}</p>
<button onClick={this.increment}>Increment</button>
</div>
);
}
}
export default Counter;
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import Counter from './App';
return (
<div>
<p>{count}</p>
<button onClick={increment}>Increment by function</button>
</div>
);
}
export default Counter;
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import Counter from './App';
function App() {
return (
<ThemeContext.Provider value="dark">
<Child />
</ThemeContext.Provider>
);
}
function Child() {
const theme = useContext(ThemeContext); // Consuming context
return <div>Current theme: {theme}</div>;
}
export default App;
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
In this example, ThemeContext.Provider defines a scope for the theme value, which is accessible in Child
via useContext.
5. Scope in useEffect and useCallback
useEffect: The useEffect hook allows you to manage side effects in your components. The scope of
variables within useEffect can be tricky, especially when dealing with asynchronous code. React
ensures that the latest state is always available inside the effect when the component re-renders.
o Example:
//app.js
import { useState,useEffect } from 'react';
import React from 'react';
function Counter() {
const [count] = useState(0);
useEffect(() => {
console.log(count); // Latest state value
}, [count]);
return <div>{count}</div>;
}
export default Counter;
//index,js
import React from 'react';
import ReactDOM from 'react-dom/client';
import Counter from './App';
const root =
ReactDOM.createRoot(document.getElementById('root'));
root.render(<Counter />);
useCallback: If you're passing a function down to child components, useCallback can help ensure
that the function reference is stable (i.e., doesn't change on every render). This helps to preserve the
scope of the function and prevent unnecessary re-renders.
6. Component Scope in React Router
When using React Router for navigation, the scope of route components can vary depending on whether
they are inside Routes or if they are connected via hooks like useParams or useLocation. These hooks give
you access to route parameters, history, and other routing-related data, creating a scoped context for the
routes.
The difference between JavaScript (JS) and JSX is mainly in their syntax and usage, particularly in the
context of React development. Here's a detailed breakdown:
1. Definition
JavaScript (JS):
o JavaScript is a programming language that is used for building dynamic content on web
pages. It provides logic, control structures, event handling, and data manipulation. JavaScript
is executed by the browser or a JavaScript engine (like Node.js).
o It is a general-purpose scripting language used for tasks such as manipulating the DOM,
handling events, and making AJAX requests.
JSX (JavaScript XML):
o JSX is a syntax extension for JavaScript, primarily used with React. It allows you to write
HTML-like code inside JavaScript files. JSX combines the structure of HTML with the
power of JavaScript, enabling you to define UI components declaratively.
o Although JSX looks similar to HTML, it is ultimately converted into JavaScript that can be
executed by the browser (React uses a tool like Babel to compile JSX into regular
JavaScript).
2. Syntax
JavaScript (JS):
o JavaScript is written in standard programming syntax using variables, functions, control
structures, and objects. Here’s an example of standard JavaScript code:
function greet(name) {
return "Hello, " + name;
}
let greeting = greet("Sangola");
console.log(greeting); // Output: Hello, Sangola
JSX:
o JSX looks like HTML but can be embedded in JavaScript code. It enables you to define the
structure of the UI inside React components. For example:
function Greeting(props) {
return <h1>Hello, {props.name}</h1>;
}
o In this example, <h1>Hello, {props.name}</h1> is JSX syntax used inside the Greeting
component. It looks like HTML, but it’s actually JavaScript code.
3. How They're Used
JavaScript (JS):
o JavaScript is used to write logic for your application, including functions, loops, conditionals,
and event handlers. It can manipulate the DOM, handle asynchronous tasks, and perform
other tasks within a web page or web application.
o Example:
Advantages of JSX
Declarative Syntax: JSX provides a declarative way to describe UI, making the code easier to read
and understand.
Better Readability: With JSX, it's easier to visualize how the UI will be structured, as it looks like
HTML.
Integration with JavaScript: JavaScript expressions and logic can be seamlessly integrated into
JSX, making it more dynamic and flexible.
Component Reusability: JSX enables component-based development, making it easier to build
reusable UI elements.
Disadvantages of JSX
Learning Curve: Beginners may find JSX initially confusing because it blends HTML-like syntax
with JavaScript.
Debugging: Since JSX is compiled into JavaScript, it can sometimes be harder to debug the
underlying code.
Tooling Dependency: JSX requires a transpiler like Babel to convert it into regular JavaScript that
the browser can understand.
React components
In React, components are the building blocks of a React application. They allow you to split the UI into
independent, reusable pieces, making development more manageable, modular, and maintainable.
Components in React can be thought of as JavaScript functions or classes that return a description of what
should appear on the screen. They are responsible for handling the view layer in the MVC (Model-View-
Controller) pattern.
Key Features of React Components
1. Reusability: Components can be reused across different parts of the application.
2. Composition: Components can be nested inside other components, allowing you to build complex
UIs.
3. Lifecycle Methods: Class components have lifecycle methods like componentDidMount,
componentDidUpdate, etc., which are useful for handling side effects.
4. Hooks: With hooks like useState, useEffect, etc., functional components can now manage state,
perform side effects, and more.
// simple component accessing example
//app.js
function Car()
{
return <h2>Hi, I am in my own new Car!</h2>;
}
export default Car;
//index.js
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import MyComponent from './App';
With the introduction of React Hooks in React 16.8, functional components can now handle state and
lifecycle methods (which were previously only available in class components), making them more powerful
and preferable in many scenarios.
Example with Hooks (State and Effect):
//app.js
import { useState, useEffect } from 'react';
function Counter()
{
const [count, setCount] = useState(0);
useEffect(() =>
{
document.title = `You clicked ${count} times`;
}, [count]);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
);
}
export default Counter;
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import Counter from './App';
//index.js
Class components can hold state (in a this.state object) and can use lifecycle methods, such as
componentDidMount, componentDidUpdate, and componentWillUnmount.
Example of State and Lifecycle Method:
//app.js
componentDidMount() {
console.log("Component has mounted");
}
render() {
return (
<div>
<p>You clicked {this.state.count} times</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Click me
</button>
</div>
);
}
}
export default Counter;
// index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import Counter from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Counter />);
With the advent of React Hooks, the usage of class components has decreased, as functional components
are more concise and flexible.
// app.js
import { useState } from 'react';
// Stateless component
function Greeting({ name }) {
return <h1>Hello, {name}!</h1>;
}
// Stateful component
function App() {
const [name] = useState("Sangola");
return <Greeting name={name} />;
}
export default App;
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
Always use the setState() method to change the state object, it will ensure that the component knows its been
updated and calls the render() method (and all the other lifecycle methods).
//app.js
class Car extends React.Component {
constructor(props) {
super(props);
this.state = {
brand: "Ford",
model: "Mustang",
color: "red",
year: 1964
};
}
render() {
return (
<div>
<h1>My {this.state.brand}</h1>
<p>
It is a {this.state.color}
{this.state.model}
from {this.state.year}.
</p>
</div>
);
}
}
Index.js
4. Pure Components
A Pure Component is a class component that only re-renders when its props or state have changed. It
implements a shallow comparison of props and state, improving performance by preventing unnecessary
re-renders.
//index,js
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import MyComponent from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<MyComponent />);
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import MyForm from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<MyForm />);
Uncontrolled Components: In uncontrolled components, the form elements maintain their own state
internally, and React doesn’t directly control it. Instead of using state to manage the input’s value,
you can use refs to directly access the DOM.
o Example: A form with an uncontrolled input field.
//app.js
import { useRef } from 'react';
function MyForm() {
const inputRef = useRef(null);
return (
<div>
<input ref={inputRef} type="text" />
<button onClick={handleSubmit}>Submit</button>
</div>
);
}
export default MyForm;
//insex.js
//app.js
function Car(props) {
return <h2>I am in my new {props.color} Car!</h2>;
}
export default Car;
// index.js
2. State:
o State is used to store data that changes over time within a component. It can be updated using the
setState method (in class components) or the useState hook (in functional components).
const [count, setCount] = useState(0);
3. Event Handling:
o React allows you to handle user interactions like clicks, key presses, and form submissions by binding
event handlers to elements.
Just like HTML DOM events, React can perform actions based on user events.
React has the same events as HTML: click, change, mouseover etc.
Adding Events
React events are written in camelCase syntax:
onClick instead of onclick.
React event handlers are written inside curly braces:
onClick={shoot} instead of onclick="shoot()".
React:
<button onClick={shoot}>Take the Shot!</button>
HTML:
<button onclick="shoot()">Take the Shot!</button>
//app.js
function Football() {
const shoot = () => {
alert("Great Shot!");
}
return (
<button onClick={shoot}>Take the shot!</button>
);
}
export default Football;
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import Football from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Football />);
return (
<button onClick={() => shoot("Goal!")}>Take the shot!</button>
);
}
export default Football;
Index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import Football from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Football />);
return (
<button onClick={(event) => shoot("Goal!", event)}>Take the
shot!</button>
);
}
export default Football;
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import Football from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Football />);
child components
In React, child components refer to components that are nested inside other components, which are called
parent components. React’s component model is hierarchical, meaning that one component can "contain"
or "compose" other components, making the UI modular and reusable.
Child Components in React
A child component can be passed data and behavior (via props) from a parent component, and it can also
communicate back to the parent by calling functions passed down as props. This allows for the exchange of
data and interactions between parent and child components.
1. How Child Components Work
A parent component renders a child component within its JSX.
The child component can receive data from the parent via props.
The child component can also send data or trigger actions to the parent through callbacks (functions passed
as props).
2. Passing Data to Child Components (Props)
In React, data is passed to child components through props. Props (short for properties) allow you to pass
dynamic data (like strings, numbers, arrays, functions) from the parent component to the child component.
Example: Parent passing data to a Child component
// app.js
// Parent component
function Parent() {
const parentData = "Hello from Parent!";
// index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import Parent from './App';
//app.js
// Parent component
import { useState } from 'react';
function Parent()
{
const [message, setMessage] = useState("");
return (
<div>
<h1>{message}</h1>
<Child sendMessage={updateMessage} />
</div>
);
}
function Child(props)
{
return (
<div>
<button onClick={() => props.sendMessage("Hello from Child!")}>
Send Message to Parent
</button>
</div>
);
}
export default Parent;
// index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import Parent from './App';
In this example:
The Parent component defines the updateMessage function and passes it as a prop (sendMessage) to
the Child component.
The Child component calls the sendMessage function when the button is clicked, which updates the state
in the parent.
4. Reusable Child Components
One of the strengths of child components is that they can be reused in different parts of your application. By
passing different props, you can change the behavior or appearance of the child component while keeping
the same logic.
Example: Reusable Child Component
//app.js
// Parent component
function Parent() {
return (
<div>
<Child message="First message" />
<Child message="Second message" />
</div>
);
}
// Child component
function Child(props) {
return <h1>{props.message}</h1>;
}
export default Parent;
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import Parent from './App';
Here, the Child component is reused twice with different messages, allowing it to be highly reusable with
different data.
5. Child Components with Event Handlers
Child components can also have their own event handlers, but they can still communicate with the parent
component by invoking functions passed as props.
Example: Handling Events in a Child Component
//app.js
import { useState } from 'react';
function Parent() {
const handleClick = () => {
alert("Button clicked in Parent");
};
// Child component
function Child(props)
{
return <button onClick={props.onButtonClick}>Click Me</button>;
}
export default Parent;
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import Parent from './App';
import Child from './App';
In this example:
The Parent component passes an event handler (onButtonClick) to the Child component as a prop.
When the button in the Child component is clicked, it triggers the handleClick function from the parent,
displaying an alert.
6. Complex Child Components with Multiple Props
You can also pass multiple props to a child component, allowing it to be more flexible.
Example: Complex Child Component
//app.js
// Parent component
function Parent() {
const user = { name: "Sangola", age: 25 };
return <Child user={user} isLoggedIn={true} />;
}
// Child component
function Child(props) {
const { name, age } = props.user;
return (
<div>
<h1>{props.isLoggedIn ? `Welcome ${name}` : "Please log in"}</h1>
<p>Age: {age}</p>
</div>
);
}
//index.js
Child.propTypes = {
name: PropTypes.string.isRequired,
age: PropTypes.number.isRequired,
};
This ensures that the Child component will only receive
props of the correct type, and if the wrong type is
passed, a warning is shown in development mode.
8. Children as Props
React provides a special prop called children. This prop allows you to pass components as children to
other components.
Example: Using children prop
//app.js
// Parent component
function Parent() {
return (
<div>
<Child>
<h1>This is content inside the child!</h1>
</Child>
</div>
);
}
// Child component
function Child(props) {
return <div>{props.children}</div>;
}
export default Parent;
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import Parent from './App';
In this example:
The Parent component passes an h1 tag as the children prop to the Child component.
The Child component renders whatever is passed in the children prop.
9. Key Concepts in Child Components
Props: Data and behavior passed down from the parent to the child component.
Communication: Child components can send data back to the parent through functions passed as props.
Event Handling: Child components can handle their own events but can also trigger parent event handlers.
Reusability: Child components are modular and reusable with different data passed through props.
Children Prop: The special children prop allows a parent to pass components or elements to a child
component.
JSX Expressions
In React, JSX expressions are the parts of JSX code that allow you to embed dynamic JavaScript code
within the JSX syntax. JSX itself is a syntax extension to JavaScript that allows you to write HTML-like
structures inside JavaScript code, but with JSX expressions, you can make your JSX dynamic by embedding
JavaScript logic directly inside the markup.
What is an Expression in JSX?
An expression in JavaScript is any valid piece of code that produces a value. These expressions can include:
Variables
Function calls
Operations (arithmetic, logical, etc.)
Conditional logic
Arrays and objects
In JSX, any valid JavaScript expression can be embedded inside curly braces {}. When JSX is compiled,
these expressions get evaluated and rendered as part of the component’s output.
1. Embedding JavaScript Expressions in JSX
The most basic form of a JSX expression is embedding JavaScript inside curly braces {}. This can include
variables, operations, and function calls.
Example:
//app.js
function Welcome(props) {
const greeting = "Hello, " + props.name;
return <h1>{greeting}</h1>;
}
export default Welcome;
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import Welcome from './App';
function Sum() {
const a = 5;
const b = 10;
return <h1>{a + b}</h1>; // Will display 15
}
export default Sum;
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import Sum from './App';
Here:
If props.isLoggedIn is true, it will display "Welcome back!".
Otherwise, it will display "Please log in".
4. Conditional Rendering in JSX (Using JavaScript)
JSX allows you to use JavaScript expressions like the ternary operator or logical AND (&&) to
conditionally render parts of the UI.
Example: Using && for Conditional Rendering
//app.js
function Notification(props) {
return (
<div>
{props.hasNewMessages && <p>You have new messages!</p>}
</div>
);
}
export default Notification;
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import Notification from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Notification hasNewMessages={true} />);
//app.js
function ItemList(props) {
const items = ["Apple", "Banana", "Cherry"];
return (
<ul>
{items.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
);
}
export default ItemList;
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import ItemList from './App';
In this example:
The map() function iterates over the items array and returns a <li> element for each item.
The key prop is required when rendering lists in React to help identify each element in the list for efficient
updates.
6. Functions as Expressions in JSX
You can invoke functions inside JSX expressions. For example, you can call a function to calculate a value
and render it.
Example:
//app.js
function calculateDiscount(price)
{
return price * 0.1;
}
function Price(props) {
return (
<div>
<h1>Original Price: ${props.price}</h1>
<h2>Discount: ${calculateDiscount(props.price)}</h2>
</div>
);
}
export default Price;
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import Price from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Price price='1000 ' />);
Here:
The calculateDiscount function is called inside the JSX expression to calculate the discount on the
price.
7. Expressions with JSX Elements (Nesting Components)
JSX expressions can also be used to pass JSX elements as children of components, allowing for the
composition of UI components.
Example:
//app.js
function Page() {
const showHeader = true;
return (
<div>
{showHeader && <Header />}
<p>This is the content of the page.</p>
</div>
);
}
export default Page;
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import Page from './App';
In this example:
The Header component is conditionally rendered based on the value of showHeader.
If showHeader is true, the Header component will be rendered.
//index.js
Here:
If props.isLoggedIn is true, it will display "Welcome back!".
Otherwise, it will display "Please log in".
Switch case operator
Sometimes it is possible to have multiple conditional renderings. In the switch case, conditional rendering is applied
based on a different state.
Example
//app.js
import React, { useState } from "react";
function GreetingComponent() {
const [timeOfDay, setTimeOfDay] = useState("morning"); // State variable
return (
<div>
{renderGreeting()} {/* Render different greetings based on timeOfDay */}
<button onClick={() => setTimeOfDay("morning")}>Morning</button>
<button onClick={() => setTimeOfDay("afternoon")}>Afternoon</button>
<button onClick={() => setTimeOfDay("evening")}>Evening</button>
</div>
);
}
export default GreetingComponent;
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import GreetingComponent from './App';
Example
Lists are used to display data in an ordered format and mainly used to display menus on websites. In React, Lists can
be created in a similar way as we create lists in JavaScript. Let us see how we transform Lists in regular JavaScript.
The map() function is used for traversing the lists. In the below example, the map() function takes an array of numbers
and multiply their values with 5. We assign the new array returned by map() to the variable multiplyNums and log it.
Keys
Keys allow React to keep track of elements. This way, if an item is updated or removed, only that item will be re-
rendered instead of the entire list.
Keys need to be unique to each sibling. But they can be duplicated globally.
Generally, the key should be a unique ID assigned to each item. As a last resort, you can use the array index as a key.
//app.js
function Car(props) {
return <li>I am a { props.brand }</li>;
}
function Garage() {
const cars = [
{id: 1, brand: 'Ford'},
{id: 2, brand: 'BMW'},
{id: 3, brand: 'Audi'}
];
return (
<>
<h1>Who lives in my garage?</h1>
<ul>
{cars.map((car) => <Car key={car.id} brand={car.brand} />)}
</ul>
</>
);
}
export default Garage;
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import Garage from './App';
React Refs
Refs is the shorthand used for references in React. It is similar to keys in React. It is an attribute which makes it possible
to store a reference to particular DOM nodes or React elements. It provides a way to access React DOM nodes or React
elements and how to interact with it. It is used when we want to change the value of a child component, without
making the use of props.
addingRefInput() {
this.callRef.current.focus();
}
render() {
return (
<div>
<h2>Adding Ref to DOM element</h2>
<input
type="text"
ref={this.callRef} />
<input
type="button"
value="Add text input"
onClick={this.addingRefInput}
/>
</div>
);
}
}
export default App;
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
function handleClick() {
callRefInput.current.focus();
}
return (
<div>
<h2>Adding Ref to Class Component</h2>
<input
type="text"
ref={callRefInput} />
<input
type="button"
value="Focus input"
onClick={handleClick}
/>
</div>
);
}
class App extends React.Component {
constructor(props) {
super(props);
this.callRefInput = React.createRef();
}
focusRefInput() {
this.callRefInput.current.focus();
}
render() {
return (
<CustomInput ref={this.callRefInput} />
);
}
}
export default App;
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
this.callRefInput = null;
this.focusRefInput = () => {
//Focus the input using the raw DOM API
if (this.callRefInput) this.callRefInput.focus();
};
}
componentDidMount() {
//autofocus of the input on mount
this.focusRefInput();
}
render() {
return (
<div>
<h2>Callback Refs Example</h2>
<input
type="text"
ref={this.setInputRef}
/>
<input
type="button"
value="Focus input text"
onClick={this.focusRefInput}
/>
</div>
);
}
}
export default App;
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
In the above example, React will call the "ref" callback to store the reference to the input DOM element when the
component mounts, and when the component unmounts, call it with null. Refs are always up-to-date before
the componentDidMount or componentDidUpdate fires. The callback refs pass between components is the same as
you can work with object refs, which is created with React.createRef().
Forwarding Ref from one component to another component
Ref forwarding is a technique that is used for passing a ref through a component to one of its child components. It can
be performed by making use of the React.forwardRef() method. This technique is particularly useful with higher-order
components and specially used in reusable component libraries. The most common example is given below.
//app.js
In the above example, there is a component TextInput that has a child as an input field. Now, to pass or forward
the ref down to the input, first, create a ref and then pass your ref down to <TextInput ref={inputRef}>. After that,
React forwards the ref to the forwardRef function as a second argument. Next, we forward this ref argument down
to <input ref={ref}>. Now, the value of the DOM node can be accessed at inputRef.current.
Syntax
const refContainer = useRef(initialValue);
Example
In the below code, useRef is a function that gets assigned to a variable, inputRef, and then attached to an attribute
called ref inside the HTML element in which you want to reference.
//app.js
import { useState, useEffect, useRef } from "react";
function App() {
const [inputValue, setInputValue] = useState("");
const count = useRef(0);
useEffect(() => {
count.current = count.current + 1;
});
return (
<>
<input
type="text"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
/>
<h1>Render Count: {count.current}</h1>
</>
);
}
In ReactJS, State and Props are two core concepts that allow you to manage and pass data between
components. Understanding how they work is fundamental to building dynamic and interactive UIs.
1. Props (short for Properties)
1. Props are inputs to components that are passed from a parent component to a child component.
2. Props are read-only and immutable, meaning a child component cannot modify the props it receives.
3. They allow you to pass data, configuration, or event handlers down to child components.
Key Characteristics of Props:
1. Read-Only: They cannot be changed by the child component. The parent controls the value of props.
2. Immutable: Props are fixed during the component’s lifecycle.
3. Dynamic: Props can change over time (due to state changes in the parent component), causing the child
component to re-render.
Example:
//app.js
function Greeting(props) {
return <h1>Hello, {props.name}!</h1>;
}
function App() {
return <Greeting name="Sangola" />;
}
export default App;
//index.js
const root =
ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
In this example:
1. The name prop is passed from the App component to the Greeting component.
2. The Greeting component receives the prop and renders it in JSX.
Passing Multiple Props:
//app.js
function UserCard(props) {
return (
<div>
<h2>{props.name}</h2>
<p>{props.age} years old</p>
</div>
);
}
function App() {
return <UserCard name="John" age={30} />;
}
export default App;
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
//app.js
import React from 'react';
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 }; // Initialize state
}
increment = () => {
this.setState({ count: this.state.count + 1 }); // Update state
}
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={this.increment}>Increment</button>
</div>
);
}
}
//app.js
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0); // Declare state
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>Increment</button>
</div>
);
}
export default Counter;
//index.js
//app.js
import React, { useState } from 'react';
function ParentComponent() {
const [count, setCount] = useState(0);
return <ChildComponent count={count} setCount={setCount} />;
}
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import ParentComponent from './App';
In this example:
The ParentComponent manages the count state.
The count and setCount are passed as props to ChildComponent.
ChildComponent can display the count and trigger a change in the parent’s state by calling setCount.
1. It does not maintain its internal state. It maintains its internal states.
2. Here, data is controlled by the parent component. Here, data is controlled by the DOM itself.
3. It accepts its current value as a prop. It uses a ref for their current values.
4. It allows validation control. It does not allow validation control.
5. It has better control over the form elements and data. It has limited control over the form elements and data.
function MyForm() {
return (
<form>
<label>Enter your name:
<input type="text" />
</label>
</form>
)
}
export default MyForm;
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import MyForm from './App';
function MyForm() {
const [name, setName] = useState("");
return (
<form>
<label>Enter your name:
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>
</label>
</form>
)
}
export default MyForm;
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import MyForm from './App';
function MyForm() {
const [name, setName] = useState("");
return (
<form onSubmit={handleSubmit}>
<label>Enter your name:
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>
</label>
<input type="submit" />
</form>
)
}
export default MyForm;
//index,js
import React from 'react';
import ReactDOM from 'react-dom/client';
import MyForm from './App';
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import MyForm from './App';
In React, the selected value is defined with a value attribute on the select tag:
//app.js
import { useState } from "react";
import ReactDOM from "react-dom/client";
function MyForm() {
const [myCar, setMyCar] = useState("Volvo");
const handleChange = (event) => {
setMyCar(event.target.value)
}
return (
<form>
<select value={myCar} onChange={handleChange}>
<option value="Ford">Ford</option>
<option value="Volvo">Volvo</option>
<option value="Fiat">Fiat</option>
</select>
</form>
)
}
export default MyForm;
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import MyForm from './App';
//app.js
import React, { Component } from 'react';
class App extends React.Component {
constructor(props) {
super(props);
this.updateSubmit = this.updateSubmit.bind(this);
this.input = React.createRef();
}
updateSubmit(event) {
alert('You have entered the UserName and CompanyName successfully.');
event.preventDefault();
}
render() {
return (
<form onSubmit={this.updateSubmit}>
<h1>Uncontrolled Form Example</h1>
<label>Name:
<input type="text" ref={this.input} />
</label>
<label>
CompanyName:
<input type="text" ref={this.input} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
export default App;
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import MyForm from './App';
Controlled Component
In HTML, form elements typically maintain their own state and update it according to the user input. In the controlled
component, the input form element is handled by the component rather than the DOM. Here, the mutable state is
kept in the state property and will be updated only with setState() method.
Controlled components have functions that govern the data passing into them on every onChange event, rather than
grabbing the data only once, e.g., when you click a submit button. This data is then saved to state and updated with
setState() method. This makes component have better control over the form elements and data.
A controlled component takes its current value through props and notifies the changes through callbacks like an
onChange event. A parent component "controls" this changes by handling the callback and managing its own state
and then passing the new values as props to the controlled component. It is also called as a "dumb component."
//app.js
import React, { Component } from 'react';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('You have submitted the input successfully: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<h1>Controlled Form Example</h1>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange}
/>
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
export default App;
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import MyForm from './App';
Nex
T
Events
Next Events are just some actions performed by a user to interact with any application or An event is an action that
could be triggered as a result of the user action or system generated event. They can be the smallest of actions, like
hovering a mouse pointer on an element that triggers a drop-down menu, resizing an application window, or
dragging and dropping elements to upload them a mouse click, loading of a web page, pressing a key, window
resizes, and other interactions are called events etc.
React has its own event handling system which is very similar to handling events on DOM elements. The react event
handling system is known as Synthetic Events. The synthetic event is a cross-browser wrapper of the browser's
native event.
Events in React are divided into three categories:
For each of these events, JavaScript provides responses. So, every time an event is performed by the user, it usually
requires some type of reaction from the application; and these reactions are defined as some functions or blocks of
code, called Event Handlers. This entire process of working with events using Event Handlers is known as Event
Management.
Event Management in ReactJS
Event management is one of the important features in a web application. It enables the user to interact with the
application. React supports all events available in a web application. React event handling is very similar to DOM
events with little changes. Following are some of the common events one can observe in React-based websites –
Clicking on a component.
Scrolling the current page.
Hovering over elements of the current page.
Submitting a form.
Redirecting to another webpage.
Loading images.
boolean bubbles
boolean cancelable
DOMEventTarget currentTarget
boolean defaultPrevented
number eventPhase
boolean isTrusted
DOMEvent nativeEvent
void preventDefault()
boolean isDefaultPrevented()
void stopPropagation()
boolean isPropagationStopped()
void persist()
DOMEventTarget target
number timeStamp
string type
Since synthetic events use a lot of resources, they are usually reused and all its properties will be nullified after
invoking the event callback to optimize their performance in the browser. SyntheticEvent has the same interface as
the native event. And as the synthetic events are authorized by the document node, native events are triggered first
followed by the synthetic events.
Adding an Event
As we have already seen, React has the same events as HTML: click, change, mouseover etc. However, the React
events are defined with a camelCase and the reaction is written inside the curly braces instead. The syntax of adding
an event differs in a functional component and class component.
Following is the syntax to add an onClick event in a functional component of React:
onClick = {action to be performed}
Following is the syntax to add an onClick event in a class component of React:
onClick = {this.action_to_be_performed}
Handling an Event
Let us now learn how to handle these events in a React application with the help of the following step-by-step
process.
Define an event handler method to handle the given event.
log() {
console.log("Event is fired");
}
React provides an alternative syntax using lambda function to define event handler. The lambda syntax is −
log = () => {
console.log("Event is fired");
}
Passing Arguments to Event Handler
There are two methods available to pass arguments to an Event Handler:
Arrow Method
Bind Method
Arrow Method
If you want to know the target of the event, then add an argument e in the handler method. React will send the
event target details to the handler method.
log(e) {
console.log("Event is fired");
console.log(e.target);
}
The alternative lambda syntax is −
log = (e) => {
console.log("Event is fired");
console.log(e.target);
}
If you want to send extra details during an event, then add the extra details as initial argument and then add
argument (e) for event target.
log(extra, e) {
console.log("Event is fired");
console.log(e.target);
console.log(extra);
console.log(this);
}
The alternative lambda syntax is as follows −
log = (extra, e) => {
console.log("Event is fired");
console.log(e.target);
console.log(extra);
console.log(this);
}
Bind Method
We can also bind the event handler method in the constructor of the component. This will ensure the availability
of this in the event handler method.
constructor(props) {
super(props);
this.logContent = this.logContent.bind(this);
}
If the event handler is defined in alternate lambda syntax, then the binding is not needed. this keyword will be
automatically bound to the event handler method.
Set the event handler method for the specific event as specified below −
<div onClick={this.log}> ... </div>
To set extra arguments, bind the event handler method and then pass the extra information as second argument.
<div onClick={this.log.bind(this, extra)}> ... </div>
The alternate lambda syntax is as follows −
<div onClick={this.log(extra, e)}> ... </div>
//app.js
import React from 'react';
import ReactDOM from 'react-dom/client';
function Football() {
const shoot = () => {
alert("Great Shot!");
}
return (
<button onClick={shoot}>Take the shot!</button>
);
}
export default Football;
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import Football from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Football />);
return (
<button onClick={() => shoot("Goal!")}>Take the shot!</button>
);
}
export default Football;
Index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import Football from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Football />);
return (
<button onClick={(event) => shoot("Goal!", event)}>Take the shot!</button>
);
}
export default Football;
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import Football from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Football />);
Example
In the below example, we have used only one component and adding an onChange event. This event will trigger
the changeText function, which returns the company name.
//app.js
import React, { Component } from 'react';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
companyName: ''
};
}
changeText(event) {
this.setState({
companyName: event.target.value
});
}
render() {
return (
<div>
<h2>Simple Event Example</h2>
<label htmlFor="name">Enter company name: </label>
<input type="text" id="companyName"
onChange={this.changeText.bind(this)}/>
<h4>You entered: { this.state.companyName }</h4>
</div>
);
}
}
export default App;
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
// Function which will validate the input data whenever submit button is clicked.
function validateForm() {
// Check if the First Name is an Empty string or not.
if (firstName.length === 0) {
alert('Invalid Form, First Name can not be empty')
return
}
if (email.length === 0) {
alert('Invalid Form, Email Address can not be empty')
return
}
if (password.length < 8) {
alert(
'Invalid Form, Password must contain greater than or equal to 8 characters.',
)
return
}
if (specialChars.includes(password[i])) {
// this means that the character is special, so increment countSpecialCharacters
countSpecialCharacters++
} else if (!isNaN(password[i] * 1)) {
// this means that the character is a digit, so increment countDigit
countDigit++
} else {
if (password[i] === password[i].toUpperCase()) {
// this means that the character is an upper case character, so increment
countUpperCase
countUpperCase++
}
if (password[i] === password[i].toLowerCase()) {
// this means that the character is lowercase, so increment countUpperCase
countLowerCase++
}
}
}
if (countLowerCase === 0) {
// invalid form, 0 lowercase characters
alert('Invalid Form, 0 lower case characters in password')
return
}
if (countUpperCase === 0) {
// invalid form, 0 upper case characters
alert('Invalid Form, 0 upper case characters in password')
return
}
if (countDigit === 0) {
// invalid form, 0 digit characters
alert('Invalid Form, 0 digit characters in password')
return
}
if (countSpecialCharacters === 0) {
// invalid form, 0 special characters characters
alert('Invalid Form, 0 special characters in password')
return
}
// if all the conditions are valid, this means that the form is valid
alert('Form is valid')
}
return (
<div className="main">
<form>
{/* Input Field to insert First Name */}
<input
placeholder="First Name"
onChange={(e) => setFirstName(e.target.value)}
/>
{/* Input Field to insert Last Name */}
<input
placeholder="Last Name"
onChange={(e) => setLastName(e.target.value)}
/>
{/* Input Field to insert Mobile Number */}
<input
placeholder="Mobile Number"
onChange={(e) => setMobile(e.target.value)}
/>
{/* Input Field to insert Age */}
<input placeholder="Age" onChange={(e) => setAge(e.target.value)} />
{/* Input Field to insert Email Address of the user */}
<input placeholder="Email" onChange={(e) => setEmail(e.target.value)} />
{/* Input Field to insert Password */}
<input
placeholder="Password"
onChange={(e) => setPassword(e.target.value)}
/>
<button
type="submit"
onClick={() => {
validateForm()
}}
>
Submit
</button>
</form>
{lastName }
{mobile }{age}
</div>
)
}
export default App
Routing: Routing is a process in which a user is directed to different pages based on their action or request.
Or
Routing is a process of binding a web URL to a specific resource in the web application.
It binds an URL to a component. React Router is used to define multiple routes in the application. When a user types
a specific URL into the browser, and if this URL path matches any 'route' inside the router file, the user will be
redirected to that particular route. React community provides many third party components to handle routing in the
React application.
React Router is a standard library system built on top of the React and used to create routing in the React application
using React Router Package. It provides the synchronous URL on the browser with data that will be displayed on the
web page. It maintains the standard structure and behavior of the application and mainly used for developing single
page web applications.
Need of React Router
React Router plays an important role to display multiple views in a single page application. Without React Router, it is
not possible to display multiple views in React applications. Most of the social media websites like Facebook, Instagram
uses React Router for rendering multiple views.
Features of React Router
Declarative Routing: React Router v6 uses the Routes and Route components to define routes declaratively,
making the routing configuration simple and easy to read.
Nested Routes: It supports nested routes, allowing for complex and hierarchical routing structures, which helps
in organizing the application better.
Programmatic Navigation: The useNavigate hook enables programmatic navigation, allowing developers to
navigate between routes based on certain conditions or user actions.
Route Parameters: It provides dynamic routing with route parameters, enabling the creation of routes that can
match multiple URL patterns.
Improved TypeScript Support: Enhanced TypeScript support ensures that developers can build type-safe
applications, improving development efficiency and reducing errors.
//app.js
import React from "react";
import {
BrowserRouter as Router,
Routes,
Route,
Link,
useNavigate,
Outlet,
} from "react-router-dom";
// Home Page Component
const Home = () => {
const navigate = useNavigate();
return (
<div>
<h2>Home Page</h2>
<button onClick={() =>
navigate("/contact")}>Go to Contact</button>
</div>
);
};
// About Page Component
const About = () => (
<div>
<h2>About Page</h2>
<nav>
<ul>
<li>
<Link to="team">Our Team</Link>
</li>
<li>
<Link to="company">Our Company</Link>
</li>
</ul>
</nav>
<Outlet />
</div>
);
// Components for other pages
const Contact = () => <h2>Contact Page</h2>;
const Team = () => <h2>Team Page</h2>;
const Company = () => <h2>Company Page</h2>;
function App() {
return (
<Router>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/contact">Contact</Link>
</li>
</ul>
</nav>
{/*Implementing Routes for respective Path */}
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />}>
<Route path="team" element={<Team />} />
<Route path="company" element={<Company />} />
</Route>
<Route path="/contact" element={<Contact />} />
</Routes>
</Router>
);
}
export default App;
//index.css
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
margin: 0;
padding: 0;
}
h2 {
text-align: center;
color: #333;
}
nav ul {
display: flex;
justify-content: center;
list-style: none;
padding: 0;
}
nav li {
margin: 0 10px;
}
nav a {
text-decoration: none;
color: #333;
}
button {
display: block;
margin: 20px auto;
padding: 10px 20px;
background-color: #007BFF;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
button:hover {
background-color: #0056b3;
}
//index.js
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
State Management:
State represents the value of dynamic properties of a React component at a given instance
i.e. State in ReactJS refers to an object that stores a component’s dynamic data and determines how the
component behaves. React provides a dynamic data store for each component. The internal data
represents the state of a React component and can be accessed using this.state member variable of the
component. Whenever the state of the component is changed, the component will re-render itself by
calling the render() method along with the new state.
Defining a State: State in React can be used with functional and class components. To work with state in a
component, there must exist a starting point, i.e. initial state. This initial state of a component must be
defined in the constructor of the component's class. Following is the syntax to define a state of any Class
Stateful Components
Stateful Components: These components maintain state that determines their behavior or appearance.
Stateful components can be either class components or functional components (with React Hooks).
o Example: A presentational component that just displays data passed to it.
// app.js
import { useState } from 'react';
// Stateless component
function Greeting({ name }) {
return <h1>Hello, {name}!</h1>;
}
// Stateful component
function App() {
const [name] = useState("Sangola");
return <Greeting name={name} />;
}
export default App;
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
Always use the setState() method to change the state object, it will ensure that the component knows its been
updated and calls the render() method (and all the other lifecycle methods).
//app.js
class Car extends React.Component {
constructor(props) {
super(props);
this.state = {
brand: "Ford",
model: "Mustang",
color: "red",
year: 1964
};
}
render() {
return (
<div>
<h1>My {this.state.brand}</h1>
<p>
It is a {this.state.color}
{this.state.model}
from {this.state.year}.
</p>
</div>
);
}
}
Index.js
In local state management, the state is only accessible and modifiable within the component it is defined in.
The useState hook in React allows developers to define and update local state within a component. The
useState hook takes in an initial value and returns an array with two elements: the current state and a
function to update the state.
The useState hook is used for managing local state within a component, while the useContext hook is used
for managing global state across multiple components. The useState hook is simpler to implement and is
great for small applications or components with limited state. However, as the application grows and the
number of stateful components increases, using the useState hook can become cumbersome. On the other
hand, the useContext hook requires more setup, but it provides a more scalable and efficient way of
managing global state in large applications.
Here’s an example of how you could use both the useState and useContext hooks in the same application:
Redux
Redux is an open-source JavaScript library used to manage application state. React uses Redux for building
the user interface. It was first introduced by Dan Abramov and Andrew Clark in 2015.
React Redux is the official React binding for Redux. It allows React components to read data from a Redux
Store, and dispatch Actions to the Store to update data. Redux helps apps to scale by providing a sensible way
to manage state through a unidirectional data flow model. React Redux is conceptually simple. It subscribes
to the Redux store, checks to see if the data which your component wants have changed, and re-renders your
component.
Redux was inspired by Flux. Redux studied the Flux architecture and omitted unnecessary complexity.
o Redux does not have Dispatcher concept.
o Redux has an only Store whereas Flux has many Stores.
o The Action objects will be received and handled directly by Store.
Why use React Redux?
The main reason to use React Redux are:
o React Redux is the official UI bindings for react Application. It is kept up-to-date with any API
changes to ensure that your React components behave as expected.
o It encourages good 'React' architecture.
o It implements many performance optimizations internally, which allows to components re-render
only when it actually needs.
Redux Architecture
React Hooks
Hooks are the new feature introduced in the React 16.8 version. It allows you to use state and other React features
without writing a class. Hooks are the functions which "hook into" React state and lifecycle features from function
components. It does not work inside classes. Hooks allow function components to have access to state and other
React features. Because of this, class components are generally no longer needed.
Hooks are backward-compatible, which means it does not contain any breaking changes. Also, it does not replace
your knowledge of React concepts.
When to use a Hooks
If you write a function component, and then you want to add some state to it, previously you do this by converting it
to a class. But, now you can do it by using a Hook inside the existing function component.
Rules of Hooks
Hooks are similar to JavaScript functions, but you need to follow these two rules when using them. Hooks rule
ensures that all the stateful logic in a component is visible in its source code. These rules are:
1. Only call Hooks at the top level
Do not call Hooks inside loops, conditions, or nested functions. Hooks should always be used at the top level of the
React functions. This rule ensures that Hooks are called in the same order each time a component renders.
2. Only call Hooks from React functions
You cannot call Hooks from regular JavaScript functions. Instead, you can call Hooks from React function
components. Hooks can also be called from custom Hooks.
3. Hooks cannot be conditional
function CountApp() {
// Declare a new state variable, which we'll call "count"
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
export default CountApp;
output:
In the above example, useState is the Hook which needs to call inside a function component to add some local state
to it. The useState returns a pair where the first element is the current state value/initial value, and the second one
is a function which allows us to update it. After that, we will call this function from an event handler or somewhere
else. The useState is similar to this.setState in class. The equivalent code without Hooks looks like as below.
App.js
import React, { useState } from 'react';
function CounterExample() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
export default CounterExample;
The above code is based on the previous example with a new feature which we set the document title to a custom
message, including the number of clicks.
Output:
Basic Hooks
o useState
o useEffect
o useContext
Additional Hooks
o useReducer
o useCallback
o useMemo
o useRef
o useImperativeHandle
o useLayoutEffect
o useDebugValue
1. useState Example
You must import Hooks from react.
Here we are using the useState Hook to keep track of the application state.
State generally refers to application data or properties that need to be tracked.
The React useState Hook allows us to track state in a function component.
State generally refers to data or properties that need to be tracking in an application.
Import useState
To use the useState Hook, we first need to import it into our component.
State generally refers to data or properties that need to be tracking in an application.
Initialize useState
We initialize our state by calling useState in our function component.
useState accepts an initial state and returns two values:
The current state.
A function that updates the state.
Example:
Initialize state at the top of the function component.
import { useState } from "react";
function FavoriteColor()
{
const [color, setColor] = useState("");
}
Notice that again, we are destructuring the returned values from useState.
The first value, color, is our current state.
The second value, setColor, is the function that is used to update our state.
function FavoriteColor() {
const [color, setColor] = useState("red");
Update State
To update our state, we use our state updater function.
import { useState } from "react";
import ReactDOM from "react-dom/client";
function FavoriteColor() {
const [color, setColor] = useState("red");
return (
<>
<h1>My favorite color is {color}!</h1>
<button
type="button"
onClick={() => setColor("blue")}
>Blue</button>
</>
)
}
//app.js
import React, { useState } from "react";
import ReactDOM from "react-dom/client";
function FavoriteColor() {
const [color, setColor] = useState("red");
return (
<>
<h1>My favorite color is {color}!</h1>
<button
type="button"
onClick={() => setColor("blue")}
>Blue</button>
<button
type="button"
onClick={() => setColor("red")}
>Red</button>
<button
type="button"
onClick={() => setColor("pink")}
>Pink</button>
<button
type="button"
onClick={() => setColor("green")}
>Green</button>
</>
);
}
Custom Hooks
A custom Hook is a JavaScript function. The name of custom Hook starts with "use" which can call other Hooks. A
custom Hook is just like a regular function, and the word "use" in the beginning tells that this function follows the
rules of Hooks. Building custom Hooks allows you to extract component logic into reusable functions.
Let us understand how custom Hooks works in the following example.
import React, { useState, useEffect } from 'react';
function CustomCounter() {
const [count, setCount] = useState(0);
const incrementCount = () => setCount(count + 1);
useDocumentTitle(`You clicked ${count} times`);
// useEffect(() => {
// document.title = `You clicked ${count} times`
// });
return (
<div>
<p>You clicked {count} times</p>
<button onClick={incrementCount}>Click me</button>
</div>
)
}
export default CustomCounter;
In the above snippet, useDocumentTitle is a custom Hook which takes an argument as a string of text which is a title.
Inside this Hook, we call useEffect Hook and set the title as long as the title has changed. The second argument will
perform that check and update the title only when its local state is different than what we are passing in.
function Timer() {
const [count, setCount] = useState(0);
useEffect(() => {
setTimeout(() => {
setCount((count) => count + 1);
}, 1000);
});
useEffect runs on every render. That means that when the count changes, a render happens, which then
triggers another effect.
This is not what we want. There are several ways to control when side effects run.
We should always include the second parameter which accepts an array. We can optionally pass
dependencies to useEffect in this array.
Effect Cleanup
Some effects require cleanup to reduce memory leaks.
Timeouts, subscriptions, event listeners, and other effects that are no longer needed should be disposed.
We do this by including a return function at the end of the useEffect Hook.
function Timer() {
const [count, setCount] = useState(0);
useEffect(() => {
let timer = setTimeout(() => {
setCount((count) => count + 1);
}, 1000);
return () => clearTimeout(timer)
}, []);
/*
Note: To clear the timer, we had to name it.
*/
3. useContext Hook
React Context
React Context is a way to manage state globally.
It can be used together with the useState Hook to share state between deeply nested components more
easily than with useState alone.
Create Context
To create context, you must Import createContext and initialize it:
import { useState, createContext } from "react";
import ReactDOM from "react-dom/client";
return (
<UserContext.Provider value={user}>
<h1>{`Hello ${user}!`}</h1>
<Component2 user={user} />
</UserContext.Provider>
);
}
return (
<>
<h1>Component 5</h1>
<h2>{`Hello ${user} again!`}</h2>
</>
);
}
Example:
//app.js
import { useState, createContext, useContext } from "react";
import ReactDOM from "react-dom/client";
function Component1() {
const [user, setUser] = useState("Jesse Hall");
return (
<UserContext.Provider value={user}>
<h1>{`Hello ${user}!`}</h1>
<Component2 />
</UserContext.Provider>
);
}
function Component2() {
return (
<>
<h1>Component 2</h1>
<Component3 />
</>
);
}
function Component3() {
return (
<>
<h1>Component 3</h1>
<Component4 />
</>
);
}
function Component4() {
return (
<>
<h1>Component 4</h1>
<Component5 />
</>
);
}
function Component5() {
const user = useContext(UserContext);
return (
<>
<h1>Component 5</h1>
<h2>{`Hello ${user} again!`}</h2>
</>
);
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Component1 />);