0% found this document useful (0 votes)
3 views

React Notes 2

React.js is a JavaScript library developed by Facebook for building user interfaces, particularly single-page applications, using a component-based architecture. It allows developers to create reusable UI components and manage dynamic content efficiently. React is popular for its speed, modularity, and scalability, making it suitable for complex applications.

Uploaded by

sainiavinash1111
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

React Notes 2

React.js is a JavaScript library developed by Facebook for building user interfaces, particularly single-page applications, using a component-based architecture. It allows developers to create reusable UI components and manage dynamic content efficiently. React is popular for its speed, modularity, and scalability, making it suitable for complex applications.

Uploaded by

sainiavinash1111
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 122

REACT.

JS
JavaScript library for building user interfaces
What is React?
• From the official React page : A JavaScript library for building user interfaces
• Its not a framework; React does only one thing – create awesome UI!
• React is used to build single page applications.
• React.js is a JavaScript library. It was developed by engineers at Facebook.
• React is a declarative, efficient, and flexible JavaScript library for building
user interfaces.
• It lets you compose complex UIs from small and isolated pieces of code
called “components”.
Client-side Javascript frameworks
• Ember : was initially released in December 2011. It is an older framework that has
less users than more modern alternatives such as React and Vue
• Angular is an open-source web application framework led by the Angular Team at
Google and by a community of individuals and corporations.
• Vue : first released in 2014; is the youngest of the big four, but has enjoyed a recent
uptick in popularity.
• React : released by Facebook in 2013. By this point, FB had already been using
React to solve many of its problems internally.
 React itself is not technically a framework; it's a library for rendering UI components.
 React is used in combination with other libraries to make applications — React and React
Native enable developers to make mobile applications; React and ReactDOM enable them
to make web applications, etc.
Components
• A Component is one of the core building blocks of React.
• Its just a custom HTML element!

• Every application you will develop in React will be made up of pieces called
components.
 Components make the task of building UIs much easier. You can see a UI broken down
into multiple individual pieces called components and work on them independently and
merge them all in a parent component which will be your final UI.
Why react
• Created and maintained by facebook
• Has a huge community on Github
• Component based architecture
• React is fast. Apps made in React can handle complex updates and still feel
quick and responsive.
• React is modular. Instead of writing large, dense files of code, you can write
many smaller, reusable files. React’s modularity can be a beautiful solution to
JavaScript’s maintainability problems.
• React is scalable. Large programs that display a lot of changing data are
where React performs best.
• React is popular.
• UI state becomes difficult to manage with vanilla Javascript
Requirements
• Ensure that NodeJS and typescript are installed
 Install TypeScript as follows:
 npm install –g typescript
Using create-react app
• npx create-react-app my-app
• cd my-app
• npm start
Understanding the folder structure
Index.html

• The root node is the HTML


element where you want to
display the result.
• It is like a container for
content managed by React.
• It does NOT have to be a
<div> element and it does
NOT have to have the
id='root
Understanding the folder structure
Understanding JSX
import React from 'react';

function App() {
/*return (
<div >
<h2>Welcome to React!</h2>
</div>
);*/
return React.createElement('div',null,'h2','Hi, welcome to React');
}
export default App;

function App() {
/*return (
<div >
<h2>Welcome to React!</h2>
</div>
);*/
return React.createElement('div',null,
React.createElement('h1',{className:'App'},'Hi welcome to React'));
}
export default App;
Understanding JSX
• Eg : const mytag = <h1>Hello React!</h1>;

const myelement = <h1>Understanding JSX!</h1>;

ReactDOM.render(myelement, document.getElementById('root'));

const myelement = (
<ul>
<li>Apples</li>
<li>Bananas</li>
<li>Cherries</li>
</ul>
);

ReactDOM.render(myelement, document.getElementById('root'));

const myelement = (
<div> If we want to return more
<h1>I am a Header.</h1> elements, we need to wrap
<h1>I am a Header too.</h1> it with one container
</div> element. Notice how we
); are using div as a wrapper
for the two h1 elements.
ReactDOM.render(myelement, document.getElementById('root'));
Creating a functional component
• Components are the essential building blocks of any app created with React
 A single app most often consists of many components.
• A component is in essence, a piece of the UI - splitting the user interface into
reusable and independent parts, each of which can be processed separately.
 Components are independent and reusable bits of code.
 It’s an encapsulated piece of logic.
 They serve the same purpose as JavaScript functions, but work in isolation and return
HTML via a render function.

function ExpenseItem(){
return <h2>Expense Item</h2>
}
export default ExpenseItem;

const ExpenseItem = () => {


return <h2>Expense Item</h2>
}
export default ExpenseItem;
Creating a functional component
• Adding our component to main component
 To use this component in your application, use similar syntax as normal HTML

• Creating components makes them


reusable and configurable.
• Reusing is simple. Eg, simply copy
paste <ExpenseItem/> multiple times
in App.js.
Another example

import React, {Component} from 'react';


import './App.css'; return (
import Person from './Person/Person'; <div className="App">
function App() { <h1> Hi, welcome to React</h1>
return ( <Person />
<div className="App"> <Person />
<h1> Hi, welcome to React</h1> <Person />
<Person /> </div>
</div> );
);
}
export default App;
Making our functional component more complex
import "./ExpenseItem.css"

const ExpenseItem = () => {


return (
<div className="expense-item">
<div>Oct 20th 2021</div>
<div className="expense-item__description">
<h2>Paid Carpenter</h2>
<p className="expense-item__price">Rs 75000</p>
</div>
</div>
)
}
export default ExpenseItem;
Components & JSX
• When creating components, you have the choice between two different ways:
• Functional components (also referred to as "presentational", "dumb" or "stateless"
components)
using ES6 arrow functions as
const cmp = () => { shown here is recommended
return <div>some JSX</div> but optional
}

• class-based components (also referred to as "containers", "smart" or "stateful"


components)

class Cmp extends Component {


render () {
return <div>some JSX</div>
}
}
Outputting dynamic content
• If we have some dynamic content in our jsx part which we want to run as javaScript
code and not interpret as text, we have to wrap it in single curly braces.

import "./ExpenseItem.css"

const ExpenseItem = () => {

const expDate = new Date(2021, 7, 11);


const expTitle = "Paid carpenter";
const expAmount = 75000

return (
<div className="expense-item">

{/* single and multiline comments in JSX */}

<div>{expDate.toISOString()}</div>
<div className="expense-item__description"> Comments in JSX
<h2>{expTitle}</h2>
<p className="expense-item__price">Rs {expAmount}</p>
</div>
</div>
)
}
export default ExpenseItem;
Outputting dynamic content – another example
//Person.js Wrap dynamic
import React from 'react'; content in JSX in {...}

const person = () => {


return <p>Hi Person i am {Math.floor(Math.random() * 30)} years old</p>
}
export default person;

function App() {
return (
<div className="App">
<h1> Hi, welcome to React</h1>
<Person />
<Person />
<Person />
</div>
);
}
}
PROPS
Passing data via ‘Props’
• “Props” stands for properties.
 It is a special keyword in React used for passing data from one component to another.
 Props are arguments passed into React components.
 props are read-only. So, the data coming from a parent component can't be changed by
the child component.
 Props are passed to components via HTML attributes.
 Props can be used to pass any kind of data such as: String, Array, Integer, Boolean,
Objects or, Functions

import HelloComponent from "./HelloComponent";

const MessageComponent = () => {


return(
<div>
<HelloComponent name="Shrilata" />
</div>
);
} const HelloComponent = (props) => {
export default MessageComponent; return (<h3>Hello, welcome {props.name}</h3>)
}
export default HelloComponent;
Passing data via ‘Props’
function App() {
return (
<div className="App">
<h2>Welcome to React!</h2>
<ExpenseItem expDate="20-12-2020" expTitle="Myntra shopping" expAmount="2500"/>
<ExpenseItem expDate="21-12-2020" expTitle="Microwave" expAmount="8000"/>
</div>
);
}
export default App; you can use as many
props as you like

const ExpenseItem = (props) => {


return (
<div className="expense-item">
<div>{props.expDate}</div>
<div className="expense-item__description">
<h2>{props.expTitle}</h2>
<p className="expense-item__price">Rs {props.expAmount}</p>
</div>
</div>
) React uses ‘props’ to pass attributes from
} ‘parent’ component to ‘child’ component.
export default ExpenseItem;
Working with props
function App() {
return (
<div className="App">
<h1> Hi, welcome to React</h1>
<Person name="Shri" age="20"/>
<Person name="Soha" age="23”>Hobbies : Coding</Person>
<Person name="sandeep" age="45"/>
</div>
);

//Person.js
import React from 'react';

const person = (props) => {


return <p>Hi i am {props.name} and i am {props.age} years old</p>
}
export default person;
React uses ‘props’ to pass attributes from
‘parent’ component to ‘child’ component.
Working with props
function App() {
const expenses = [
{
title: 'Groceries',
amount: 900,
date: new Date(2020, 7, 14),
},
{ title: 'New TV', amount: 34000, date: new Date(2021, 2, 12) },
{ title: 'SofaSet', amount: 25000, date: new Date(2021, 2, 28),
}
];

return (
<div className="App">
<h2>Welcome to React!</h2>
<ExpenseItem expDate={expenses[0].date} expTitle={expenses[0].title}
expAmount={expenses[0].amount}/>
<ExpenseItem expDate={expenses[1].date} expTitle={expenses[1].title}
expAmount={expenses[1].amount}/>
<ExpenseItem expDate={expenses[2].date} expTitle={expenses[2].title}
expAmount={expenses[2].amount}/>
</div>
);
}
export default App;
“Javascript” in components
const ExpenseItem = (props) => {
const month = props.expDate.toLocaleString('en-US', {month: 'long'});
const day = props.expDate.toLocaleString('en-US', {day: '2-digit'});
const year = props.expDate.getFullYear();

return (
<div className="expense-item">
<div>
<div>{month}</div>
<div>{day}</div>
<div>{year}</div>
</div>
<div className="expense-item__description">
<h2>{props.expTitle}</h2>
<p className="expense-item__price">Rs {props.expAmount}</p>
</div>
</div>
)
}
export default ExpenseItem;
import ExpenseDate from "./ExpenseDate";
const ExpenseItem = (props) => { Splitting components further
return (
<div className="expense-item">
<ExpenseDate date={props.expDate}/>
<div className="expense-item__description">
<h2>{props.expTitle}</h2>
<p className="expense-item__price">Rs {props.expAmount}</p>
</div>
</div>
)
}
export default ExpenseItem;

import "./ExpenseDate.css"

const ExpenseDate = (props) => {


const month = props.date.toLocaleString('en-US', {month: 'long'});
const day = props.date.toLocaleString('en-US', {day: '2-digit'});
const year = props.date.getFullYear();
return (
<div className="expense-date">
<div className="expense-date__month">{month}</div>
<div className="expense-date__day">{day}</div>
<div className="expense-date__year">{year}</div>
</div>
);
}
export default ExpenseDate;
EVENTS AND EVENT HANDLING
Listening to events and working with event handlers
const ExpenseItem = (props) => {

let btnHandler = () => {


console.log("Button clicked!")
}

return (
<div className="expense-item">
<ExpenseDate date={props.expDate}/>
<div className="expense-item__description">
<h2>{props.expTitle}</h2>
<p className="expense-item__price">Rs {props.expAmount}</p>
</div>
<button onClick={btnHandler}>Change Title</button>
</div>
)
}
export default ExpenseItem;

No parenthesis ()
STATEFUL COMPONENTS
React State
• The state is a built-in React object that is used to contain data or information
about the component.
• A component’s state can change over time; whenever it changes, the
component re-renders.
 The change in state can happen as a response to user action or system-generated
events and these changes determine the behavior of the component and how it will
render.
• A component with state is known as stateful component.

• State allows us to create components that are dynamic and interactive.


 State is private, it must not be manipulated from the outside.
 Also, it is important to know when to use ‘state’, it is generally used with data that is
bound to change.
Component without state
const ExpenseItem = (props) => {

let title = props.expTitle;

let btnHandler = () => {


title = "updated expense"
console.log("Button clicked!")
}

return (
<div className="expense-item">
<ExpenseDate date={props.expDate}/>
<div className="expense-item__description">
<h2>{title}</h2>
<p className="expense-item__price">Rs {props.expAmount}</p>
</div>
<button onClick={btnHandler}>Change Title</button>
</div>
)
}
export default ExpenseItem;
React Hooks
• Hooks allow us to "hook" into React features such as state and lifecycle methods
 React Hooks are special functions provided by React to handle a specific functionality
inside a React functional component.
 Eg React provides useState() function to manage state in a functional component.
 When a React functional component uses React Hooks, React Hooks attach itself into
the component and provides additional functionality.

• You must import Hooks from react


 Eg : import React, { useState } from "react"; Here - useState is a Hook to keep track of
the application state.

• There are some rules for hooks:


 Hooks can only be called inside React function components.
 Hooks can only be called at the top level of a component.
 Hooks cannot be conditional
 Hooks will not work in React class components.
 If you have stateful logic that needs to be reused in several components, you can build
your own custom Hooks
Working with “state” in functional component
• The React useState Hook allows us to track state in a function component.
• To use the useState Hook, we first need to import it into our component.
 import { useState } from "react";
 We initialize our state by calling useState in our function component.

import React, {useState} from 'react';

const UseStateComponent = () => {


useState(); //hooks go here
}

 useState accepts an initial state and returns two values:


1. The current state.
2. A function that updates the state.
 Eg: function FavoriteColor() {
const [color, setColor] = useState("");
}

o The first value, color, is our current state.


o The second value, setColor, is the fuction that is used to update our state.
o Lastly, we set the initial state to an empty string: useState("")
Working with “state” in functional component
import React, {useState} from 'react';

const UseStateComponent = () => {


const [counter, setCounter] = useState(0); //hooks go here

const btnHandler = () => {


setCounter(counter+1);
console.log(counter, " button clicked")
}
return(
<div>
Counter : {counter} &nbsp;&nbsp;
<button onClick={btnHandler}>increment counter</button>
</div>
);
}
export default UseStateComponent;
Working with “state” in functional component
import React, {useState} from 'react'

const ExpenseItem = (props) => {

const [title, setTitle] = useState(props.expTitle);

let btnHandler = () => {


setTitle("updated expense")
console.log("Button clicked!")
}

return (
<div className="expense-item">
<ExpenseDate date={props.expDate}/>
<div className="expense-item__description">
<h2>{title}</h2>
<p className="expense-item__price">Rs {props.expAmount}</p>
</div>
<button onClick={btnHandler}>Change Title</button>
</div>
)
}
export default ExpenseItem;
props and state
• props and state are CORE concepts of React.
 Actually, only changes in props and/ or state trigger React to re-render your components
and potentially update the DOM in the browser
• Props : allow you to pass data from a parent (wrapping) component to a child
component.
 Eg : AllPosts Component : “title” is the custom property (prop) set up on the
custom Post component.
 Post Component: receives the props argument. React will pass one argument to your
component function; an object, which contains all properties you set up on <Post ... /> .
 {props.title} then dynamically outputs the title property of the props object - which is
available since we set the title property inside AllPosts component

//AllPosts //Post
const posts = () => { const post = (props) => {
return ( return (
<div> <div>
<Post title="My first Post" /> <h1>{props.title}</h1>
<Post title="My second Post" /> </div>
</div> );
); }
}
props and state
• State : While props allow you to pass data down the component tree (and hence
trigger an UI update), state is used to change the component’s, well, state from
within.
 Changes to state also trigger an UI update.
 Example: NewPost Component: this component contains state . Only class-based
components can define and use state . You can of course pass the state down to
functional components, but these then can't directly edit it.

class NewPost extends Component { // state can only be accessed in class-based components!
state = {
counter: 1
};

render () { // Needs to be implemented in class-based components! Return some JSX!


return (
<div>{this.state.counter}</div>
);
}
}
props and state
• Props are immutable.
• They should not be updated by the component to which they are passed.
• They are owned by the component which passes them to some other
component.

• State is something internal and private to the component.


• State can and will change depending on the interactions with the outer world.
• State should store as simple data as possible, such as whether an input
checkbox is checked or not or a CSS class that hides or displays the
component
Simple example : props + state
import React, {useState} from 'react'
import ChildComponent from './ChildComponent';

const ParentComponent = () => {


const [uname, setUname] = useState('Shrilata')
const [email, setEmail] = useState('shrilata@gmail.com')

return(
<ChildComponent uname={uname} email={email} />
);
} function App() {
export default ParentComponent; return (
<div className="App">
<h2>Welcome to React!</h2>
const ChildComponent = (props) => { <ParentComponent />
return( ...
<div>
<div>Name : {props.uname}</div>
<div>Email : {props.email}</div>
</div>
);
}
export default ChildComponent;
USING FORM FOR INPUT
const NewExpense = () => {
return(
Adding form inputs <div className="new-expense">
<ExpenseForm />
import "./ExpenseForm.css" </div>
const ExpenseForm = () => { );
return( }
<form> export default NewExpense;
<div className="new-expense__controls">
<div className="new-expense__control">
<label>Title</label>
<input />
</div>
<div className="new-expense__control">
<label>Amount</label>
<input type="number"/>
</div>
<div className="new-expense__control">
<label>Date</label>
<input type="date" min="2019-01-01"
max="2022-12-31" />
</div>
</div>
<div className="new-expense__actions">
<button type="submit">Add Expense</button>
</div>
</form>
);
}
export default ExpenseForm;
Listening to user input
const ExpenseForm = () => {

const titleChangeHandler = (event) => {


console.log(event.target.value)
}
return(
<form>
<div className="new-expense__controls">
<div className="new-expense__control">
<label>Title</label>
<input onChange={titleChangeHandler}/>
</div>
...
</div>
<div className="new-expense__actions">
<button type="submit">Add Expense</button>
</div>
</form>
);
}
export default ExpenseForm;
Storing input into state – working with multiple states
import React, {useState} from 'react';
const ExpenseForm = () => {

const [inputTitle, setInputTitle] = useState('')


const [inputAmount, setInputAmount] = useState('')
const [inputDate, setInputDate] = useState('')

const titleChangeHandler = (event) => {


setInputTitle(event.target.value)
}
const amountChangeHandler = (event) => {
setInputAmount(event.target.value)
}
const dateChangeHandler = (event) => {
setInputDate(event.target.value)
}
return(
<form>
<div className="new-expense__controls">
<div className="new-expense__control">
<label>Title</label> <input onChange={titleChangeHandler}/>
</div>
<div className="new-expense__control">
<label>Amount</label>
<input type="number" onChange={amountChangeHandler}/>
</div> ...
Form submission
Form submission – extracting data, 2-way binding
const ExpenseForm = () => {

const [inputTitle, setInputTitle] = useState('')


const [inputAmount, setInputAmount] = useState('')
const [inputDate, setInputDate] = useState('')

const titleChangeHandler = (event) => {...}


const amountChangeHandler = (event) => {...}
const dateChangeHandler = (event) => {...}

const submitHandler = (event) => {


event.preventDefault();
const expenseData = {
title:inputTitle,
amount:inputAmount, return(
date:inputDate <form onSubmit={submitHandler}>
} <div className="new-expense__controls">
console.log(expenseData) <div className="new-expense__control">
setInputAmount('') <label>Title</label>
setInputDate('') <input value={inputTitle}
setInputTitle('') onChange={titleChangeHandler}/>
} </div>
...
</form>
);
}
Passing data from child to parent component
const NewExpense = () => {

const saveExpenseDataHandler = (inputExpenseData) => {


const expenseData = {
...inputExpenseData,
id:Math.random().toString()
}
console.log("In NewExpense ",expenseData)
}
return(
<div className="new-expense">
<ExpenseForm onSaveExpenseData={saveExpenseDataHandler}/>
</div>
); const ExpenseForm = (props) => {
}
...
export default NewExpense; const submitHandler = (event) => {
event.preventDefault();
const expenseData = {
title:inputTitle,
amount:inputAmount,
date: new Date(inputDate)
}
//console.log(expenseData)
props.onSaveExpenseData(expenseData);
...
}
Passing data from child to parent
function App() {
const expenses = [...];

const addExpenseHandler = expense => {


console.log("In App component ", expense)
}

return (
<div className="App">
<h2>Welcome to React!</h2>
<NewExpense onAddExpense={addExpenseHandler} />
...
); const NewExpense = (props) => {
}
export default App; const saveExpenseDataHandler = (inputExpenseData) => {
const expenseData = {
...inputExpenseData,
id:Math.random().toString()
}
//console.log("In NewExpense ",expenseData)
props.onAddExpense(expenseData)
}
return(...);
}
export default NewExpense;
LIFTING STATE UP
Lifting state up in React.js
• In a typical application, you pass a lot of state down to child components as props.
 These props are often passed down multiple component levels.
 That's how state is shared vertically in your application.
• Often there will be a need to share state between different components.
 The common approach to share state between two components is to move the state to
common parent of the two components.
 This approach is called as lifting state up in React.js
 React components can manage their own state
 Often components need to communicate state to others
 Siblings do not pass state to each other directly
 State should pass through a parent, then trickle down

App

C1 C2

C11 C12 C21


Lifting state up – simple example
import React, {useState} from 'react'
import Display from './Display'
import Button from './Button'

const ClickCounter = () => {


const [counter, setCounter] = useState(0)

const incrCounter = () => { const Display = (props) => {


setCounter(counter + 1) return <p>{props.message}</p>;
} }
return( export default Display;
<div>
<Button onClick={incrCounter}>Button</Button>
<Display message={`Clicked ${counter} times`}/>
</div>
);
}
export default ClickCounter;

const Button = (props) => {


return <button onClick={props.onClick}>Click me</button>;
}
export default Button;
A small aside – add filter to date
const ExpensesFilter = (props) => {

const selectChangeHandler = (event) => {


console.log(event.target.value)
props.onSelectYear(event.target.value)
}
return (
<div className='expenses-filter'> App

<div className='expenses-filter__control'>
<label>Filter by year</label>
<select onChange={selectChangeHandler}> ExpenseItem NewExpense ExpensesFilter

<option value='2022'>2022</option>
<option value='2021'>2021</option>
<option value='2020'>2020</option> ExpenseDate ExpenseForm
<option value='2019'>2019</option>
</select>
</div> function App() {
</div> const [filteredYear, setFilteredYear] = useState(2020);
);
}; const selectYearHandler = filteredValue => {
export default ExpensesFilter; setFilteredYear(filteredValue)
}
return (
<div className="App">
<h2>Welcome to React!</h2>
<ExpensesFilter onSelectYear={selectYearHandler}/>
WORKING WITH LISTS AND
CONDITIONALS
const SimpleListComponent = () => {
const nums = [1,2,3,4,5] Working with lists
const updatedNums = nums.map((num)=>{
return <li>{num*num}</li>;
});

const items =[{name:'Item-1'}, {name:'Item-2'}]


const updatedItems = items.map(item => (
<p>{item.name}</p>
))

const students = [{name:"Anita",rollno:101},


{name:"Sunita",rollno:102},
{name:"Kavita",rollno:103}]
const updatedStudents = students.map(student => (
<tr>
<td>Name {student.name} </td>
<td>Rollno {student.rollno} </td>
</tr>
))
return(
<div>
<h2> Numbers List</h2> {updatedNums}
<h2> Items List</h2> {updatedItems}
<h2> Students List</h2>
<table border="1">{updatedStudents}</table>
</div>
);}
export default SimpleListComponent
Working with lists in child component
import SimpleListChildComponent from "./SimpleListChildComponent";

const SimpleListComponent = () => {


const nums = [1,2,3,4,5]

const items =[{name:'Item-1'}, {name:'Item-2'}]

const students = [{name:"Anita",rollno:101},


{name:"Sunita",rollno:102},
{name:"Kavita",rollno:103}]
return(
<div> const SimpleListChildComponent = (props) => {
<SimpleListChildComponent
nums={nums} const nums = props.nums;
items={items} const updatedNums = nums.map(...);
students={students} /> const items = props.items
</div> const updatedItems = items.map(...)
);
} const students = props.students;
export default SimpleListComponent const updatedStudents = students.map(...)

return(...);
}
export default SimpleListChildComponent;
Working with the expenses list
const expenses = [
{ title: 'Groceries’, amount: 900, date: new Date(2020, 7, 14)},
{ title: 'New TV', amount: 34000, date: new Date(2021, 2, 12) },
{ title: 'SofaSet', amount: 25000, date: new Date(2021, 2, 28)}
];
return (
<div className="App">
<h2>Welcome to React!</h2>
<ExpenseItem
expDate={expenses[0].date}
expTitle={expenses[0].title}
expAmount={expenses[0].amount}
/>
<ExpenseItem
expDate={expenses[1].date}
expTitle={expenses[1].title}
expAmount={expenses[1].amount}
/>
<ExpenseItem
expDate={expenses[2].date}
expTitle={expenses[2].title}
expAmount={expenses[2].amount}
/>
</div>
);
}
Working with the expenses list
function App() {
const expenses = [
{ title: 'Groceries', amount: 900, date: new Date(2020, 7, 14)},
{ title: 'New TV', amount: 34000, date: new Date(2021, 2, 12) },
{ title: 'Sofa Set', amount: 25000, date: new Date(2021, 2, 28)}
];
return (
<div className="App"> {expenses.map(expense =>
<h2>Welcome to React!</h2> (<ExpenseItem
expDate={expense.date}
{expenses.map(expense => { expTitle={expense.title}
return <ExpenseItem expAmount={expense.amount}
expDate={expense.date} />))
expTitle={expense.title} }
expAmount={expense.amount}
/>
})}
{/* <ExpenseItem
expDate={expenses[0].date}
expTitle={expenses[0].title}
expAmount={expenses[0].amount}
/> ... */}
</div>
);
}
export default App;
const DUMMY_EXP = [
Using stateful lists
{ title: 'Groceries', amount: 900, date: new Date(2020, 7, 14)},
{ title: 'New TV', amount: 34000, date: new Date(2021, 2, 12) },
{ title: 'New Sofa Set', amount: 25000, date: new Date(2021, 2, 28)}
];
function App() {
const [expenses, setExpenses] = useState(DUMMY_EXP)

const addExpenseHandler = expense => {


setExpenses(prevArr => {return [expense, ...prevArr]})
}
return (
<div className="App">
<h2>Welcome to React!</h2>
<NewExpense onAddExpense={addExpenseHandler} />

{expenses.map(expense => (<ExpenseItem


expDate={expense.date}
expTitle={expense.title}
expAmount={expense.amount}
/>))
}
</div>
);
}
export default App;
Lists and keys

const DUMMY_EXP = [
{ id:101, title: 'Groceries', amount: 900, date: new Date(2020, 7, 14)},
{ id:102,title: 'New TV', amount: 34000, date: new Date(2021, 2, 12) },
{ id:103,title: 'New Sofa Set', amount: 25000, date: new Date(2021, 2, 28)}
];

function App() {

const [expenses, setExpenses] = useState(DUMMY_EXP)


...
return (
<div className="App">
...
{expenses.map(expense => (
<ExpenseItem
key={expense.id}
expDate={expense.date}
expTitle={expense.title}
expAmount={expense.amount}
/>))
}
...
Lists and keys
• When creating a list in JSX, React may show you an error and ask for a key.
 Keys are unique identifiers that must be attached to the top-level element inside a map.
 Keys are used by React to know how to update a list whether adding, updating, or deleting
items.
 This is part of how React is so fast with large lists.
 Keys are a way to help React know how to efficiently update a list.
 We can add a key using the key prop like so:

<div>
{people.map(person => (
<p key={person.name}>{person.name}</p>
))}
</div>
Implementing filters
function App() {
const [expenses, setExpenses] = useState(DUMMY_EXP)
const [filteredYear, setFilteredYear] = useState(2020);

const filteredExpensesArr = expenses.filter(expense =>{


return expense.date.getFullYear().toString() === filteredYear;
})

...
const selectYearHandler = filteredValue => {
setFilteredYear(filteredValue)
}

return (
<div className="App">
<h2>Welcome to React!</h2>
<NewExpense onAddExpense={addExpenseHandler} />
<ExpensesFilter onSelectYear={selectYearHandler}/>
{filteredExpensesArr.map(expense => (
<ExpenseItem
key={expense.id}
expDate={expense.date}
expTitle={expense.title}
expAmount={expense.amount}
/>))
}
Rendering content conditionally
• Conditional rendering means to render a specific HTML element or React
component depending on a prop or state value.
 In a conditional render, a React component decides based on one or several conditions
which DOM elements it will return.
 For instance, based on some logic it can either return a list of items or a text that says
"Sorry, the list is empty".

if(condition_is_met) {
renderSectionOfUI();
}
Rendering content conditionally : example
/*const users = [
{ id: '1', firstName: 'Shrilata', lastName: 'T' },
{ id: '2', firstName: 'Anita', lastName: 'Patil' },
];*/
const users = []
if (!list.length) {
function ListUsers() { return <p>Sorry, the list is empty.</p>;
return ( }
<div>
<List list={users} />
</div> function Item({ item }) {
); return (
} <li>
{item.firstName} {item.lastName}
function List({ list }) { </li>
if (!list) { );
return null; }
} export default ListUsers;
return (
<ul>
{list.map(item => (
<Item key={item.id} item={item} />
))}
</ul>
);
}
Rendering content conditionally : Expense tracker example

{filteredExpensesArr.length ==0 ? <p>No expenses found</p> :


filteredExpensesArr.map(expense => (
<ExpenseItem
key={expense.id}
expDate={expense.date}
expTitle={expense.title}
expAmount={expense.amount}
/>))
}
Rendering content conditionally : one more example
const NewExpense = (props) => {
const [showForm, setShowForm] = useState(false)

const showFormHandler = () => {


setShowForm(true)
}
const saveExpenseDataHandler = (inputExpenseData) => {...}
return(
<div className="new-expense">
{!showForm && <button onClick={showFormHandler}>Add New Expense </button>}
{showForm && <ExpenseForm onCancel={stopShowForm}
onSaveExpenseData={saveExpenseDataHandler}/>}
</div>
);
}
export default NewExpense;

//ExpenseForm
<div className="new-expense__actions">
<button type="button"
onClick={props.onCancel}>Cancel</button>
<button type="submit">Add Expense</button>
</div>
CLASS-BASED COMPONENTS
const HelloComponent = (props) => {
Functional components are regular
return (<h3>Hello, welcome user!!</h3>)
javascript functions which return
}
renderable results (typically JSX)
export default HelloComponent;

class HelloComponent extends Component{


render(){ Class based components are
return (<h3>Hello, welcome user!!</h3>) defined using Javascript classes
} where a render method defines the
} to-be-rendered output
export default HelloComponent;
Class-based components : Examples
import React, {Component} from 'react';
class HelloComponent extends Component{
render(){
return (<h2>Hello class-based component</h2>)
}
}
export default HelloComponent;

import './User.css';
import React, {Component} from 'react';

class User extends Component{


render(){
return <li className='user'>Hello User</li>
}
}; function App() {
export default User; return (
<div className="App">
<h1> Welcome to React</h1>
<HelloComponent />
<User />
</div>
);
}
Class-based components : passing into props
import React, {Component} from 'react'; function App() {
import User from './User' return (
<div className="App">
const DUMMY_USERS = [ <h1> Welcome to React</h1>
{ id: 'u1', name: 'Shrilata' }, <Users />
{ id: 'u2', name: 'Soha' }, </div>
{ id: 'u3', name: 'Sia' }, );
]; }

class Users extends Component{


render(){
return(
<div>
<User name={DUMMY_USERS[0].name} />
<User name={DUMMY_USERS[1].name} />
<User name={DUMMY_USERS[2].name} />
</div>
); import './User.css';
} import React, {Component} from 'react';
}
export default Users; class User extends Component{
render(){
return (<li className='user'>Hello {this.props.name}</li>);
}
};
export default User;
React State : Example
import React, {Component} from 'react';
import './App.css';
import StatefulComponent from "./StatefulComponent/StatefulComponent";

class App extends Component {


render() { import React,{Component} from 'react';
return (
<div> class statefulComponent extends Component{
<StatefulComponent /> state = {
</div> name: "Shrilata",
); email: "shrilata@gmail.com",
} address:"Pune"
} }
export default App; render(){
return(
<div>
<h3>Name : {this.state.name}</h3>
<h3>Email : {this.state.email}</h3>
<h3>Address : {this.state.address}</h3>
</div>
);
}
}
export default statefulComponent;
State and props
const person = (props) => {
return (
<div>
<p>Hi i am {props.name}
class App extends Component { and i am {props.age} years old</p>
state = { </div>
persons:[ )
{name:"Shri",age:20}, }
{name:"Soha",age:23}, export default person;
{name:"Sandeep",age:30},
]
}
render() {
return (
<div className="App">
<h1> Hi, welcome to React</h1>
<button>Switch name</button>
<Person name={this.state.persons[0].name} age={this.state.persons[0].age}/>
<Person name={this.state.persons[1].name} age={this.state.persons[1].age}>
Hobbies : Coding
</Person>
<Person name={this.state.persons[2].name} age={this.state.persons[2].age}/>
</div>
);
}
}
LIFECYCLE EVENTS
Lifecycle Events
• React class components can have hooks for several lifecycle events
 During the lifetime of a component, there’s a series of events that gets called, and to
each event you can hook and provide custom functionality.
 React lifecycle methods are a series of events that happen from the birth of a React
component to its death.
 There are 4 phases in a React component lifecycle:
o initial
o Mounting
o Updating
o Unmounting

class HelloComponent extends Component{


constructor(){
super();
this.state = {message: “hello” }
}
render(){
return (<h2>Hello World</h2>)
}
}
Lifecycle methods
• React lifecycle methods:
 Each React lifecycle phase has a number of lifecycle methods that you can override
to run code at specified times during the process.
 These are popularly known as component lifecycle methods.

• Initialisation phase:
 Constructor(props): This is a special function that is called when new components
are created. In this, we initialize the state or props of the component.
Lifecycle methods
• The mounting phase refers to the phase during which a component is created and
inserted to the DOM.
• The following methods are called in order.
 ComponentWillMount(): This function is called immediately before mounting occurs. It
is called right before the first rendering is performed.
 render(): You have this method for all the components created. It returns the Html node.

 componentDidMount(): This method is called right after the


react component is mounted on DOM or you can say that it
is called right after render method executed for the first time
 Here we can make API call, foreg, interact with dom or
perform any ajax call to load data.

class HelloComponent extends Component{


componentDidMount(){
console.log("Mounted component")
}
render(){
return <h1>Hello</h1>
}
}
Lifecycle methods
• Update: In this state, the dom is interacted by a user and
updated. For example, you enter something in the textbox,
so the state properties are updated.
 The component is re-rendered whenever a change is made to
react component’s state or props, you can simply say that the
component is updated.
• Following are the methods available in update state:
 shouldComponentUpdate() : called when the component is
updated.
 componentDidUpdate() : after the component is updated.

• UnMounting: this state comes into the picture when the Component is not required
or removed.
• Following are the methods available in unmount state:
 ComponentWillUnmount(): called when the Component is removed or destroyed.
import React, {Component} from 'react';

class LifecycleComponent extends Component {


constructor(props) {
super(props);
this.state = {name: ''};

this.UpdateName = this.UpdateName.bind(this);
this.testclick = this.testclick.bind(this);
}

UpdateName(event) {
this.setState({name: event.target.value});
}

testclick(event) {
alert("The name entered is: "+ this.state.name);
}

componentDidMount() {
console.log('Mounting State : calling method componentDidMount');
}

shouldComponentUpdate() {
console.log('Update State : calling method shouldComponentUpdate');
return true;
}
componentDidUpdate() {
console.log('Update State : calling method
componentDidUpdate')
}
componentWillUnmount() {
console.log('UnMounting State : calling method
componentWillUnmount');
}

render() {
return (
<div>
Enter Your Name:<input type="text"
value={this.state.name} onChange={this.UpdateName} /><br/>
<h2>{this.state.name}</h2>
<input type="button"
value="Click Here"
onClick={this.testclick} />
</div>
);
}
}

export default LifecycleComponent;

Lifecycle Methods (kirupa.com)


ERROR BOUNDARIES
Using Error Boundaries
const person = (props) => {
const rnd = Math.random();
if(rnd > 0.7){
throw new Error("Something went wrong");
}
return (
...
)
};
export default person;

class Users extends Component{

componentDidUpdate(){
if(this.props.users.length == 0)
throw new Error("No users in list!")
}
...

• A JavaScript error in a part of the UI shouldn’t break the whole app.


• To solve this problem for React users, React 16 introduces a new concept of
an “error boundary”.
Using Error Boundaries
import React, {Component} from 'react';
class ErrorBoundary extends Component{
state = {
hasError:false,
errorMessage:''
}
componentDidCatch = (error, info) => {
Use it like this:
this.setState({hasError:true, errorMessage:error});
<ErrorBoundary>
}
<Artists />
render(){
</ErrorBoundary>
if(this.state.hasError)
return <h1>{this.state.errorMessage}</h1>
else
return this.props.children
}
}
export default ErrorBoundary;

• Error boundaries are React components that catch JavaScript errors anywhere in their child
component tree, log those errors, and display a fallback UI instead of the component tree that
crashed. Error boundaries catch errors during rendering
• https://reactjs.org/docs/error-boundaries.html
• React.Component – React (reactjs.org)
Using Error Boundaries
function App() {
return (
<div className="App">
<h1> Welcome to React</h1>
<ErrorBoundary >
<Person />
</ErrorBoundary>
</div>
);
}
FORMS AND FORMS VALIDATION
Handling user input the right way
Controlled Components and Uncontrolled components
• React forms present a unique challenge because you can either allow the
browser to handle most of the form elements and collect data through React
change events, or you can use React to fully control the element by setting
and updating the input value directly.
 The first approach is called an uncontrolled component because React is not setting
the value.
 The second approach is called a controlled component because React is actively
updating the input.

• In HTML, form data is usually handled by the DOM.


• In React, form data is usually handled by the components.
 When the data is handled by the components, all the data is stored in the
component state.
Controlled Inputs in class components
• An input is said to be “controlled” when React is responsible for maintaining and
setting its state.
 The state is kept in sync with the input’s value, meaning that changing the input will
update the state, and updating the state will change the input.

class ControlledInput extends React.Component {


state = { name: '' };

handleInput = (event) => {


this.setState({name: event.target.value });
}
handleSubmit = (event) => {
alert('A name was submitted: ' + this.state.name);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
Name : <input value={this.state.name}
onChange={this.handleInput} />
<input type="submit" value="Submit" />
</form>
);
}
}
Controlled Inputs using React hooks (functional components)
import React, {useState} from 'react'

const SimpleInput = (props) => {


const [inputName, setInputName] = useState('')

const inputNameHandler = (event) => {


setInputName(event.target.value)
}

const formSubmitHandler = event => {


event.preventDefault();
console.log(inputName)
}
return (
<form onSubmit={formSubmitHandler}>
<div className='form-control'>
<label htmlFor='name'>Your Name</label>
<input type='text' id='name' onChange={inputNameHandler}/>
</div>
<div className="form-actions">
<button>Submit</button>
</div>
</form>
);
};
export default SimpleInput;
Controlled Inputs
• Controlled inputs open up the following possibilities:
• instant input validation: we can give the user instant feedback without having to
wait for them to submit the form (e.g. if their password is not complex enough)
• instant input formatting: we can add proper separators to currency inputs, or
grouping to phone numbers on the fly
• conditionally disable form submission: we can enable the submit button after
certain criteria are met (e.g. the user consented to the terms and conditions)
• dynamically generate new inputs: we can add additional inputs to a form based
on the user’s previous input (e.g. adding details of additional people on a hotel
booking)
Handling Multiple Form Inputs
class ControlledLoginForm extends React.Component {
state = {
username: '', • {username: ‘shrilata’} //where username is
email: '' event.target.name which is field name ie
}; username
handleInput = (event) => { • {email: ‘Shrilata@gmail.com’} //where email is
let name = event.target.name; event.target.name which is field name ie email
let val = event.target.value;
this.setState({[name]: val});
console.log(this.state)
}
handleSubmit = (event) => {
alert('A name was submitted: ’
+ this.state.username);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<h3>Hello {this.state.username} {this.state.email}</h3>
Name : <input name="username" onChange={this.handleInput} /><br />
Email : <input name="email" onChange={this.handleInput} />
<input type="submit" value="Submit" />
</form>
); }
}
One more
example

class MultipleInputFields extends Component {

state = {
name:'',
onservation:'',
color:'',
size:'',
}
handleChanges = (event) => {
let name = event.target.name;
let val = event.target.value;
this.setState({[name]: val});
console.log(this.state)
};
submitFormHandler = (event) => {
event.preventDefault();
console.log("from submit ", this.state);
};
render(){
const colors = ['Blue', 'Red', 'Green', 'Yellow'];
const sizes = ['Small', 'Medium', 'Large', 'XL', 'XXL', '3XL'];
return (
<form onSubmit={this.submitFormHandler}>
<div className='form-control'>
<label>Name:</label>
<input name="name" type="text" value={this.state.name} onChange={this.handleChanges} />
</div>
<div className='form-control'>
<label>Observation:</label>
<textarea name="observation" value={this.state.observation} onChange={this.handleChanges} />
</div>
<div className='form-control'>
<label>Desired color:</label>
<select name="color" value={this.state.color} onChange={this.handleChanges}>
{colors.map((color, i) => <option key={i} value={color.toLowerCase()}>{color}</option>)}
</select>
</div>
<div >
<label>T-shirt Size:</label>
{sizes.map((size, i) =>
<label key={i}> {size}
<input
name="size" value={size.toUpperCase()} checked={this.state.size === size.toUpperCase()}
onChange={this.handleChanges} type="radio" />
</label>
)}
</div>
<div className="form-actions">
<button type="submit">Submit</button>
</div>
</form>
)}
}
export default MultipleInputFields;
Controlled components : Summary
• A controlled component is bound to a value, and its adjustments will be
handled in code by using event-based callbacks.
 Here, the input form variable is handled by the react itself rather than the DOM.
 In this case, the mutable state is maintained in the state property and modified using
setState().
• Controlled components have functions which regulate the data that occurs at
each on Change event.
 This data is subsequently saved in the setState() method and updated. It helps
components manage the elements and data of the form easier.

• You can use the controlled component when you create:
 Forms validation so that when you type, you always have to know the input value to
verify whether it is true or not!
 Disable submission icon, except for valid data in all fields
 If you have a format such as the input for a credit card
Validation
class ControlledInputValidation1 extends React.Component {
state = { age: '' };

handleInput = (event) => {


let nam = event.target.name;
let val = event.target.value;
if (nam === "age") {
if (!Number(val))
alert("Age must be a number");
}
this.setState({[nam]: val});
}
handleSubmit = (event) => {
alert('A age was submitted: ' + this.state.age);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
Age : <input name="age" value={this.state.age} onChange={this.handleInput}
/>
<input type="submit" value="Submit" />
</form>
);
}
}
Uncontrolled Inputs
• “uncontrolled” form inputs: React doesn’t track the input’s state.
 HTML input elements naturally keep track of their own state as part of the DOM, and
so when the form is submitted we have to read the values from the DOM elements
themselves.

• “uncontrolled” form inputs: React doesn’t track the input’s state.


 If the DOM handles the data, then the form is uncontrolled, and if the state of the
form component manages the data, then the form is said to be controlled

 Uncontrolled components are inputs that do not have a value property. In opposite
to controlled components, it is the application's responsibility to keep the component
state and the input value in sync.

 In order to do this, React allows us to create a “ref” (reference) to associate with an


element, giving access to the underlying DOM node
Uncontrolled Inputs
• In uncontrolled components form
data is being handled by DOM itself.
• For example here we can reference
form values by name
• This is quick and dirty way of handling
forms. It is mostly useful for simple
forms or when you are just learning
React.

• HTML input elements keep track of


their own state
 When the form is submitted we
typically read the values from the
DOM elements ourselves
Uncontrolled Inputs
• “ref is used to receive the form value from DOM.
 To enable this, React allows us to create a “ref” (reference) to associate with an element,
giving access to the underlying DOM node.
 Refs provide a way to access DOM nodes or React elements created in the render
method.
 Refs are created using React.createRef() and attached to React elements via the ref
attribute.
 Refs are commonly assigned to an instance property when a component is constructed so
they can be referenced throughout the component.

class MyComponent extends React.Component {


constructor(props) {
super(props);
this.myRef = React.createRef();
}
render() {
return <div ref={this.myRef} />;
}
}
Uncontrolled Inputs
import React, {Component} from 'react'; • You initialize a new ref in the
class SimpleForm extends Component { constructor by calling
constructor(props) { React.createRef, assigning it to
super(props); an instance property so it’s
// create a ref to store the DOM element available for the lifetime of the
this.nameEl = React.createRef(); component.
} • In order to associate the ref with
an input, it’s passed to the
handleSubmit = (e) => { element as the
e.preventDefault(); special ref attribute.
alert(this.nameEl.current.value); • Once this is done, the input’s
} underlying DOM node can be
accessed via
render() { this.nameEl.current.
return (
<form onSubmit={this.handleSubmit}>
<label>Name:
<input type="text" ref={this.nameEl} />
</label>
<input type="submit" name="Submit" />
</form>
)
}
}
export default SimpleForm;
class LoginForm extends Component {
constructor(props) {
super(props);
Another example : Login form
this.nameEl = React.createRef();
this.passwordEl = React.createRef();
this.rememberMeEl = React.createRef();
}
handleSubmit = (e) => {
e.preventDefault();
const data = {
username: this.nameEl.current.value,
password: this.passwordEl.current.value,
rememberMe: this.rememberMeEl.current.checked,
}
console.log(data)
}
render(){
return (
<form onSubmit={this.handleSubmit}>
<fieldset><legend>Login Form</legend>
<input type="text" placeholder="username" ref={this.nameEl} /><br></br>
<input type="password" placeholder="password" ref={this.passwordEl} /><br></br>
<label><input type="checkbox" ref={this.rememberMeEl} />Remember me
</label><br></br>
<button type="submit" className="myButton">Login</button>
</fieldset>
</form>
);
}}
COMPOSITION VS. INHERITANCE
Composition over Inheritance
• Composition and inheritance are the approaches to use multiple components
together in React.js .
• This helps in code reuse.
• React recommend using composition instead of inheritance as much as
possible and inheritance should be used in very specific cases only.
• Composition works with functions as well as classes both.
class Automobile { Inheritance in JS
constructor() {
this.vehicleName = automobile;
this.numWheels = null;
}
printNumWheels() {
console.log(`This ${this.vehicleName} has ${this.numWheels} wheels`);
}
}
class Car extends Automobile {
constructor() {
super(this);
this.vehicleName = 'car';
this.numWheels = 4;
}
}
class Bicycle extends Automobile {
constructor() {
super(this);
this.vehicleName = 'bike';
this.numWheels = 2;
}
}
const car = new Car();
const bike = new Bicycle();
car.printNumWheels() // This car has 4 wheels
bike.printNumWheels() // This bike has 2 wheels
class Parent extends React.Component {
constructor(props) {
super(props);
this.methodA = this.methodA.bind(this);
}

methodA() {
console.log("methodA in parent class"); Console output
}

render() {
return false;
}
}

import Parent from "./parent";

class Child extends Parent {


constructor() {
super();
}
render() {
console.log("In child class, calling parent method...");
this.methodA();
return false;
}
}
Composition
• Composition is a code reuse technique where a larger object is created by
combining multiple smaller objects.

class App extends React.Component {


render() {
return <Toolbar theme="dark" />;
}
}

function Toolbar(props) {
return (
<div>
<ThemedButton theme={props.theme} />
</div>
);
}

class ThemedButton extends React.Component {


render() {
return <Button theme={this.props.theme} />;
}
}
class App extends Component {
state = {
date:new Date()
...
}
...
return (
<div className="container">
<NewsHeader className="news" subject="Sports"
date={this.state.date.toString()} />

const newsHeader = (props) => {


return(
<div>
<h1>News for {props.date}</h1>
<h2>News Heading : {props.subject}</h2>
<NewsContent title="Content Title-1" content="Lots of Content-1" />
<NewsContent title="Content Title-2" content="Lots of Content-2" />
<NewsContent title="Content Title-3" content="Lots of Content-3" />

const author = (props) => {


const newsContent = (props) => { return(
return( <h6>Author for {props.title} - {props.name}</h6>
<div>
{/*complex code that filters out news based on subject*/}
<h4><b><i>News Title {props.title}</i></b></h4>
<h4>News Content : {props.content}</h4>
<Author title={props.title} name="Shrilata" />
CONTEXT
Context
• Context is designed to share data that can be considered “global” for a tree of React
components, such as the current authenticated user, theme, or preferred language

class App extends React.Component {


render() {
return <Toolbar theme="dark" />;
}
}

function Toolbar(props) {
return (
<div>
<ThemedButton theme={props.theme} />
</div>
);
}

class ThemedButton extends React.Component {


render() {
return <Button theme={this.props.theme} />;
}
}
React Context API
• Store the state in a Context value in the common ancestor component (called
the Provider Component), and access it from as many components as
needed (called Consumer Components), which can be nested at any depth
under this ancestor.
• This solution has the same benefits as the Props solution, but because of
what could be called “hierarchical scoping”, it has the added benefit that any
component can access the state in any Context that is rooted above itself in
React’s hierarchy, without this state needing to be passed down to it as
props.
• React.js takes care of all the magic behind the scenes to make this work.

• Primary situations where the React Context


API really shines are:
 When your state needs to be accessed or set
from deeply nested components.
 When your state needs to be accessed or set
from many child components.
Three aspects to using React Contexts
• 1) Defining the Context object so we can use it.
 If we wanted to store data about the current user of a web app, we could create a
UserContext that can be used in the next two steps:
// Here we provide the initial value of the context Note: It doesn’t matter where this
const UserContext = React.createContext({ Context lives, as long as it can be
currentUser: null, accessed by all components that need
}); to use it in the next two steps.

• 2) Providing a value for a Context in the hierarchy.


 Assuming you had an AccountView component, you might provide a value like this

const AccountView = (props) => {


const [currentUser, setCurrentUser] = React.useState(null);
return (
{/* Here we provides the actual value for its descendents */}
<UserContext.Provider value={{ currentUser: currentUser }}>
<AccountSummary/>
<AccountProfile/>
</UserContext.Provider>
);
};
Three aspects to using React Contexts
• 3) Accessing the current Context value lower in the hierarchy.
 If the AccountSummary component needed the user, we could have just passed it as a
prop. But let’s assume that it doesn’t directly access the user data, but rather contains
another component that does:

// Here we don't use the Context directly, but render children that do.
const AccountSummary = (props) => {
return (
<AccountSummaryHeader/>
<AccountSummaryDashboard/>
<AccountSummaryFooter/>
);
};

 All three of these child components may not want to access the current user’s data. But as
an example, let’s just look at the AccountSummaryHeader component:
const AccountSummaryHeader = (props) => {
// Here we retrieve the current value of the context
const context = React.useContext(UserContext);
return (
<section><h2>{context.currentUser.name}</h2> </section>
);
};
Context
• Using context, we can avoid passing props through intermediate elements
const ThemeContext = React.createContext('light');
class App extends React.Component {
render() {
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
);
}
}
// A component in the middle doesn't have to pass the theme down explicitly anymore
function Toolbar() {
return (
<div>
<ThemedButton />
</div>
);
}
class ThemedButton extends React.Component {
static contextType = ThemeContext;
render() {
return <Button theme={this.context} />;
}
}
Bringing Bootstrap into your React App
• After creating your app project:
• ..Demo\second-app>npm install --save react-bootstrap bootstrap@3
• Then start the app : npm start

• In Index.js, put these as the 1st 2 lines:


• import 'bootstrap/dist/css/bootstrap.css';
• import 'bootstrap/dist/css/bootstrap-theme.css’;

• Now use Bootstrap classes in App.js or any other component:


• Eg :

render(){
return(
<div className=“container”>
<h1 className="text-danger">TODO LIST </h1>
REDUX
Because state management can be hard
What is state
• Eg: const state = { <div className={this.state.signUpModal.open ? 'hidden' : ''}>
posts: [], Sign Up Modal
signUpModal: { </div>
open: false
}
}

• state references the condition of something at a particular point in time, such as


whether a modal is open or not.
• In a React component the state holds data which can be rendered to the user.
• The state in React could also change in response to actions and events: in fact you
can update the local component’s state with this.setState().
• So, in general a typical JavaScript application is full of state. For example, state is:
 what the user sees (data)
 the data we fetch from an API
 the URL
 the items selected inside a page
 eventual errors to show to the user
State can be complex
• Even an innocent single page app could grow out of control without clear
boundaries between every layer of the application. This holds particularly true
in React.
 You can get by with keeping the state within a parent React component (or in
context) as long as the application remains small.
 Then things will become tricky especially when you add more behaviours to the app.
At some point you may want to reach for a consistent way to keep track of state
changes.
Create a Redux application
npx create-react-app redux-app
cd redux-app
npm install redux react-redux

import React from 'react';


import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

//STORE -> GLOBALISED STATE

//ACTION -> INCREMENT

//REDUCER

//DISPATCH

ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
Create a Redux application
import {createStore} from 'redux’;
• Step-1 : Create the store: const myStore = createStore(reducer-name)

• Step-2 : Create action


const increment = () => {
return {
type :'INCREMENT' //name of the action
}
}
const decrement = () => {
return {
type :'DECREMENT' //name of the action
}
}

• Step-3 : Create reducer const counter = (state=0, action) => {


switch(action.type){
case "INCREMENT":
return state + 1;
case "DECREMENT":
return state - 1;
}
}
let store = createStore(counter)
Create a Redux application
• Step-4 : display store on console
• store.subscribe(() => console.log(store.getState()))

• Step-5 : dispatch the action


• store.dispatch(increment()); //dispatches the increment action

• Step-6 : Execute the app.


Start server
• npm start
Need for Redux
• Redux offers a solution to storing all your application state in one place called
“Store”
• Components then “dispatch” state changes to store, not directly to other
components
• Components that need to be aware of state changes can “subscribe” to the store
• The center of every Redux application is the store. A "store" is a container that
holds your application's global state.
 A store is a JavaScript object with a few special functions and abilities that make it
different than a plain global object:
 You must never directly modify or change the state that is kept inside the Redux store
 Instead, the only way to cause an update to the state is to create a plain action object
that describes "something that happened in the application", and then dispatch the
action to the store to tell it what happened.
 When an action is dispatched, the store runs the root reducer function, and lets it
calculate the new state based on the old state and the action
 Finally, the store notifies subscribers that the state has been updated so the UI can be
updated with the new data.
Actions, reducers and dispatchers
• An action is a plain JavaScript object that has a type field. You can think of
an action as an event that describes something that happened in the
application.
 The type field should be a string that gives this action a descriptive name. Eg
"todoAdded“ or “depositFunds” or “incrementCounter”

• A reducer is a function that receives the current state and an action object,
decides how to update the state if necessary, and returns the new state:
(state, action) => newState.
 You can think of a reducer as an event listener which handles events based on the
received action (event) type.

• The Redux store has a method called dispatch. The only way to update the
state is to call store.dispatch() and pass in an action object.
 The store will run its reducer function and save the new state value inside, and we
can call getState() to retrieve the updated value:
My original index.js
//original React imports let store = createStore(counter);
import {createStore} from 'redux';
//Display it in console
//STORE -> GLOBALISED STATE store.subscribe(() =>
console.log(store.getState()));
//ACTION -> INCREMENT
const increment = () => { //DISPATCH
return { store.dispatch(increment());
type :'INCREMENT' //name of the action store.dispatch(decrement());
}
} ReactDOM.render(
const decrement = () => { <React.StrictMode>
return { <App />
type :'DECREMENT' //name of the action </React.StrictMode>,
} document.getElementById('root')
} );

//REDUCER
const counter = (state=0, action) => {
switch(action.type){
case "INCREMENT":
return state + 1;
case "DECREMENT":
return state - 1;
}
}
//reducers/counter.js
const counterReducer = (state=0, action) => { Create a Redux app
switch(action.type){
case "INCREMENT":
return state + 1;
case "DECREMENT":
return state - 1; //src/index.js
default: return null; import {createStore} from 'redux';
} import allReducers from "./reducers";
}
export default counterReducer; const store = createStore(allReducers);

//reducers/isLogged.js
const loggedReducer = (state=false, action) => {
switch(action.type){
case "SIGNIN": //reducers/index.js
return !state; import counterReducer from "./counter";
default: import loggedReducer from "./isLogged";
return state; import {combineReducers} from 'redux';
}
} const allReducers = combineReducers({
export default loggedReducer; counter : counterReducer,
isLogged:loggedReducer
})
export default allReducers;
//src/index.js
//Original code:
const store = createStore(allReducers);
//New code:
const store = createStore(allReducers,
window.__REDUX_DEVTOOLS_EXTENSION__ && windo
w.__REDUX_DEVTOOLS_EXTENSION__());
//src/index.js
import {createStore} from 'redux';
import allReducers from "./reducers"; const counterReducer =
import {Provider} from 'react-redux'; (state=0, action) => {…}

const myStore = createStore(allReducers,


window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__());

ReactDOM.render(
<React.StrictMode>
<Provider store={myStore}>
<App />
</Provider>
</React.StrictMode>,
App.js : displaying state Allows you to extract data
from the Redux store
state, using a selector
import './App.css'; function.
import {useSelector} from 'react-redux';

function App() {
const counter = useSelector(state => state.counter);
const isLogged = useSelector(state => state.isLogged);

return (
<div className="App"> I set the isLogged
<h1>Welcome to Redux</h1> state to true
<h3>Counter : {counter}</h3>
{isLogged ? <h3> Some valuable info here</h3> : ''}
</div>
);
}

export default App;


//actions/index.js
Modifying state export const increment = () => {
return {
type :'INCREMENT'
}
}
export const decrement = () => {
import './App.css';
return {
import {useSelector, useDispatch} from 'react-redux';
type :'DECREMENT'
import {increment} from './actions';
}
import {decrement} from './actions';
}
function App() {
const counter = useSelector(state => state.counter);
const isLogged = useSelector(state => state.isLogged);
const dispatch = useDispatch();

return (
<div className="App">
<h1>Welcome to Redux</h1>
<h3>Counter : {counter}</h3>
<button onClick={() => dispatch(increment())}>+</button>
<button onClick={() => dispatch(decrement())}>-</button>
{isLogged ? <h3> Some valuable info here</h3> : ''}
</div>
);
}
export default App;

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy