Introduction
React.js is a Javascript library for creating user interference (UI). Ui means any elements on the website like cards, buttons, images, etc. Use in front-end.
What are the Components of React?
Components are like functions in JavaScript. In function, we first write the function and use it anywhere anytime help of invoking (calling) the function. so components are like this we first build the component and it is used anywhere. both are reusable.
Above there is one component named video. in the video component, there are two components thumbnil and like button (sub-components). we use these components anywhere like function.
In components, we use not only HTML but also JavaScript & CSS. before react.js we first write html file then it's CSS and then JS. but in React we built components. inside the component, we write HTML, CSS, and JS for each component. so we can use it anywhere.
we write react in JSX (JavaScript Syntax Extension) form. in JSX we write HTML into JS.
What is JSX?
JSX means JavaScript Syntax Extension. It is not real JavaScript. in JSX we write HTML inside JS. In the browser, it converts pure JS through Babel.
What is Babel?
Babel is a JavaScript compiler to converts JSX code into pure JS.
above image left side is JSX and the right side is pure JS converted by Babel.
Set up a local environment
There are two tools to create a react app. first is
Create-React-App and the second is
Vite. the first tool is traditional but today people use Vite because
Vite is much faster than Create-React-App.
Install Vite
follow commands : npm create vite@latest
it create folder automatically. and install npm pakages , run command in inside folder :
npm install
Than we start a server , run this command : npm run dev
we give a localhost link to open project, so copy this link and enter in browser go give output like here :
Folder Srtucture
There are three main files in react which show in src(source) folder which is main folder.
1.App.jsx
2.main.jsx
3.index.html
App.jsx file is the main file. all code we write in app.jsx , we can't touch today other two files.
index.css use for style the index.html elements & App.css for style the App.jsx file.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React</title>
</head>
<body>
<div id="root"></div> // it is main tag to show all components
<script type="module" src="/src/main.jsx"></script> // main.jsx
</body>
</html>
div tag which id is root is main tag.
main.jsx :
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.jsx'
import './index.css'
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<App /> // App.jsx
</React.StrictMode>,
)
this file select the root id and
render it on index.html.
App.jsx :
import { useState } from 'react'
import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import './App.css'
function App() { // app component
const [count, setCount] = useState(0)
return (
<>
<div>
<a href="https://vitejs.dev" target="_blank">
<img src={viteLogo} className="logo" alt="Vite logo" />
</a>
<a href="https://react.dev" target="_blank">
<img src={reactLogo} className="logo react" alt="React logo" />
</a>
</div>
<h1>Vite + React</h1>
<div className="card">
<button onClick={() => setCount((count) => count + 1)}>
count is {count}
</button>
<p>
Edit <code>src/App.jsx</code> and save to test HMR
</p>
</div>
<p className="read-the-docs">
Click on the Vite and React logos to learn more
</p>
</>
)
}
export default App // export this app. jsx into main.jsx
App.jsx >>>>> main.jsx >>>>>> index.html
Our 1st App
let`s create 1st app. show this image, we write only button tag here so give output below like this.
App.jsx :
import './App.css'
function App() {
return <button>hii</button>;
}
export default App
output :
this button has style auto from app.css file.
but, we can't use double tags or multiple tags at in return. example :
import './App.css'
function App() {
return <button>hii</button>
<button>hii</button>; // it give error.
}
export default App
it give error.
but, we can use tag inside multiple tags. example :
import './App.css'
function App() {
return (
<div> // main tag
<h1>heding 1</h1> // 1st subtag
<h1>heding 2</h1> // 2nd subtag
</div>
);
}
export default App
Create 1st Component
we create a Title component.
import './App.css'
function Title(){ // new component
return (
<h1>hii i am title</h1>
);
}
function App() {
return (
<div>
<h1>heding 1</h1>
<Title/> // render it
<h1>heding 2</h1>
</div>
);
}
export default App
output :
so we can render the component by two way. <Title/> & <Title></Title>
generally we write components in different files and it`s name is the component name & than export it and import to App.jsx file.
we can render the components multiple times inside div tag. example :
import './App.css'
function Title(){
return (
<h1>hii i am title</h1>
);
}
function Description(){ // new component
return (
<h3>hii i am desription</h3>
);
}
function App() {
return (
<div>
<h1>heding 1</h1>
<Title/>
<Description/>
<Title/>
<Description/>
<h1>heding 2</h1>
</div>
);
}
export default App
Import - Export
we create a file name : Title.jsx :
function Title(){
return (
<h3>hii i am title</h3>
);
}
export default Title; // export it by default method.
App.jsx :
import './App.css'
import Title from './Title'; // import only Title component.
function App() {
return (
<div>
<Title/>
<Title/>
</div>
);
}
export default App
So , we use two method of import and export. When we create multiple components into one file so we export it by this Syntax : export { Title,Description,Image,Button };
and import it by syntax : import { Title,Description,Image,Button } from "./Title.jsx" ;
1. Return a single root element
2. Close all the tags ( <Tag/> || <Tag> </Tag> )
3. camelCase most of the things use
4. In jsx file use class atribute as className
In JavaScript, class is a keyword for define the classes. and in html, class is attribute for define class of elements. but we cannot use class keyword in jsx file as html attribute because it is keyword for js. that`s why we use className as attribute for define class in elements in jsx files.
import './App.css'
import Title from './Title';
function App() {
return (
<div className='msint'> // class attribute used as className keyword in camelCase
<Title/>
<Title/>
</div>
);
}
export default App;
React Fragment
It's allow to group a list of children without adding extra nodes to the DOM. above we use <div> for parent, but we use blank tag <> </> , so extra node not create in DOM.
import './App.css'
import Title from './Title';
function App() {
return (
<> // blank tag not consider as DOM.
<Title/>
<Title/>
</>
);
}
export default App;
JavaScript in JSX with Curly braces
We write pure javaScript code in JSX with help of { }.
function Title(){
return (
<>
<h1> 2*2 = {2*2} </h1> // pure js with curly braces. // output : 2*2 = 4
</>
);
}
export default Title;
we also describe variable and use it ,
function Title(){
let name = "shreeraj";
return (
<>
<h1> 2*2 = {2*2} </h1> // 2*2 = 4
<h2>hii, {name.toUpperCase()}</h2> // pure js // out : hii, SHREERAJ
</>
);
}
export default Title;
Structuring Components
here right side photo is multiple files to get srtucture our code.
so create different files for each components and combine these files and create combo component and then import in App.jsx file.
Style the Components
We create each css file for each component. and simply import it.
Title.css :
.Title {
border: 5px solid white;
margin: auto;
padding: 0 5px 0 5px;
}
Title.jsx :
import "./Title.css"; // simple import
function Title(){
return (
<div className="Title"> // className & Function name & file name -- same
<h1>hiii how are you? </h1>
<h3>hello i am fine...</h3>
</div>
);
}
export default Title;
Each & every component should,
JSX File Name == Function Name == CSS File Name == className
example : Title.jsx , Title.css , className = "Title", function Title(){//}
Props
Props are the info that you pass to a JSX tag. it is like a function parameter.
Title.jsx :
import "./Title.css"
// props 👇function Title({title,price = 1}){ // title & price are props. like paremeters
// price default value = 1
return (
<div className="Title">
<h1>{title} </h1> // title prop
<h3>{price}</h3> // price prop
</div>
);
} // we also write props.title & props.price into h1 and h3 tag and
above we write props only.
export default Title;
App.jsx :
import './App.css'
import Title from './Title';
function App() { // use title & price props
return (
<>
<Title title="hello" price={50000}/> // price as a number. choose this ..
<Title title="hello" price="100"/> // price as a string.
</>
);
}
export default App
output :
Passing Array & Object To Props
Title.jsx :
import "./Title.css"
function Title({title,price = 1,features,features2}){ // props
return (
<div className="Title">
<h1>{title} </h1>
<h3>{price}</h3>
<h4>{features}</h4> // array
<h5>{features2}</h5> // object
</div>
);
}
export default Title;
App.jsx :
import './App.css'
import Title from './Title';
function App() {
let options = ["hii","hello"]; // create a new array
let object = {a:"hii",b:"hello"}; // create a new object
return (
<>
<Title title="hello" price={50000} features={options}/> // pass array
<Title title="hello" price="100" features2={object.a} /> // pass object
// we can`t pass whole object like {object} , it give error
so we pass object and it`s key like {object.a}
</>
);
}
export default App;
output :
so array all elements show in output without any comma for seperator. 👆
we can also pass array and object direcly like this ...👇
Title.jsx :
import "./Title.css"
function Title({title,price = 1,features,features2}){
return (
<div className="Title">
<h1>{title} </h1>
<h3>{price}</h3>
<h4>{features}</h4>
<h5>{features2.a}</h5> // in case of object we cannot print whole object we
print only object elements when we pass object directly.
</div>
);
}
export default Title;
App.jsx :
import './App.css'
import Title from './Title';
function App() {
// let options = ["hii","hello"];
// let object = {a:"hii",b:"hello"};
return (
<>
<Title
title="hello"
price={50000}
features={["hii","hello"]} // array pass directly
features2={{a:"hii",b:"hello"}} // object write directly but access only one ele..
/>
</>
);
}
export default App
Rendering Array
We print elements of array by two methods.
1. write <li> tag inside array :
import './App.css'
import Title from './Title';
function App() {
let options = [<li>"hii"</li>,<li>"hello"</li>]; // inside array.
return (
<>
<Title title="hello" price={50000} features={options}/>
</>
);
}
export default App;
output :
2. with help of map function :
App.jsx :
import './App.css'
import Title from './Title';
function App() {
let options = ["hii","hello"];
return (
<>
<Title title="hello" price={50000} features={options}/> // simple pass array.
</>
);
}
export default App;
Title.jsx :
import "./Title.css"
function Title({title,price = 1,features}){
const list = features.map((ele)=><li>{ele}</li>); // map function for add <li> tag.
return (
<div className="Title">
<h1>{title} </h1>
<h3>{price}</h3>
<h4>{list}</h4> // pass list.
</div>
);
}
export default Title;
output : it is same as above output.
Conditional Statements
we show here examples and all output will be same. in all examples we have use only one concept, if price > 30000 than we give 5% discount.
1. if-else
import "./Title.css"
function Title({title,price = 1}){
if(price>30000){ // if price gt then 30000 so we get 5 % discount.
return (
<div className="Title">
<h1>{title} </h1>
<h3>{price}</h3>
<h4>5% discount hure</h4> // discount here
</div>
);
} else{ // if price not gt then 30000 so we can't get 5 % discount.
return (
<div className="Title">
<h1>{title} </h1>
<h3>{price}</h3>
</div>
);
}
}
export default Title;
App.jsx: (it will be same in all example)
import './App.css'
import Title from './Title';
function App() {
return (
<>
<Title title="hello" price={50000} /> //above 30000
<Title title="hello" price={10000} /> // below 30000
</>
);
}
export default App;
output : (it will be same)
problem :
code repeat two times in if else.
2. Ternary Operator / Conditional Operator
import "./Title.css"
function Title({title,price = 1}){
return (
<div className="Title">
<h1>{title} </h1>
<h3>{price}</h3>
<p>{price > 30000 ? "discount 5%" : ""}</p> // ternary operator
</div>
);
}
export default Title;
output with problem :
problem : if price is not gt than 30000 so print empty <p> tag . this is add in DOM.
3. only use JS
import "./Title.css"
function Title({title,price = 1}){
return (
<div className="Title">
<h1>{title} </h1>
<h3>{price}</h3>
{price > 30000 ? <p>discount 5%</p> : null} // not add in DOM. so problem solve
// also write : { price>30000 && <p>discount 5%</p> }
</div>
);
}
export default Title;
problem solve.
Dynamic Component Styling
We style the component which have price gt than 300000, set bg color = "pink" .
import "./Title.css"
function Title({title,price = 1}){
let isDiscount = price > 30000 ; // create var
// use conditional operator with bg color.
const styles = {backgroundColor : isDiscount?"pink" : ""};
return (
<div className="Title" style={styles} >
// style is attribute for apply style
<h1>{title} </h1>
<h3>{price}</h3>
{ isDiscount ? <p>discount 5%</p> : null}
</div>
);
}
export default Title;
In CSS we write backgroung-color but in case of JSX we write backgroundColor. beacause JSX use always camelCase.
Example :
in CSS : background-color , border-radius , font-size , font-weight , font-color , etc.. properties
in JSX : backgroundColor , borderRadius , fontSize , fontWeight , fontColor , etc..
install React Dev Tool for chrome
before install these tool it give some msg in console.
After install it :
if we click on components than :
we show heirrarchy of components and it`s details. so it is very useful.. download now....
Events In React
before react we write events with help of DOM selectors like document qureySelector, id or class selectors. but in react we can write events simply.
Handling Click Events
example:
Button.jsx :
function btnClick(){ // for button click
console.log("button was clicked");
}
function paraClick(){ // for paraagraph click
console.log("para was clicked");
}
export default function Button(){
return(<>
<button onClick={btnClick}>click me</button> // dont't write btnClick() beacause
if you write than it run auto
without click btn. so dont`t write ().
<p onClick={paraClick}>this is para</p>
// onClick work in all elements.
</>)
} // this file in imported on App.jsx and give result in below img.
output :
it is like hover , double click , etc.. events. check in
MDN reference.
example :
Button.jsx :
function btnClick(){
console.log("button was clicked");
}
function paraClick(){
console.log("para was clicked");
}
export default function Button(){
return(<>
<button onDoubleClick={btnClick}>click me</button> // onDoubleClick
<p onMouseOver={paraClick}>this is para</p> // onMouseOver use for when mouse
is hover into paragraph then run func.
</>)
}
Event Object
In Event Object we show many properties like type, preventEvent,etc.. show in below example.
Form.jsx :
function submitForm(event){
console.log("form submitted");
console.log(event); // print event object
}
export default function Form(){
return(<form>
<input placeholder="enter name"/>
<button onClick={submitForm}>submit</button>
</form>)
} // import into App.jsx
In output when we enter name & click submit than in console we show submitForm function quickly or rpidly but we loose it rapidly , it`s like spark . so this is problem in react forms.
solution : event.preventDefault()
Form.jsx :
function submitForm(event){
event.preventDefault(); // it prevent spark of event matlab je defalt ma hoy
tene prevent kari nakhe. jethi aapne event object
jova madshe. niche photo jovo..
console.log("form submitted");
console.log(event);
}
export default function Form(){
return(<form>
<input placeholder="enter name"/>
<button onClick={submitForm}>submit</button>
</form>)
}
output :
So, preventDefault is property of event object use for preventing the defaut events in forms .
we also write code like this :
export default function Form(){
return(<form onSubmit={submitForm}> // into form tag as attribute.
<input placeholder="enter name"/>
<button >submit</button> // auto connect this event.
</form>)
}
State in React
State is a built-in react object that is used to contain data or info about the component. a component`s state can change over time; whenever it changes, the component re-renders.
When we use normal variables in react than it`s functionality can be changed but UI can`t change. example we try to understand click button to update it`s value. see below example.
Clickbtn.jsx :
let count = 0; // define var count
function clickMe(){
count += 1; // when click function count updates it`s value + 1.
console.log(count); // print in console.
}
export default function Click(){
return(
<>
<h3>click count : {count}</h3> // pass count value
<button onClick={clickMe}>Update Count</button> // click to update count value.
</>
);
} // import in App.jsx.
Output : When click button count variable value update in console, but not update in UI. so that is problem here . & solution is : React State
Before 2019 react use class components((class <class-name>{//})), today use function components (function <func-name>(){//}). in class components there are many features here, but in function components these features can`t include. so these problem solved by Hooks.
Hooks are the functions that use State & other react features without writing a class. today there are 15 Hooks in react.
useState()
it is a react hook that add a state variable to your component. In this function we pass initialState or initial Value. it returns array, included two property, one is initial value & other is Updater set Function which updates state variable value.
import { useState } from "react"; // import useState from react. it done auto while
use useState().
export default function Click(){
let resultArr = useState(10); // use useState & pass initial value = 10.
console.log(resultArr); // return arr see below img.
return(
<>
<h3>click count : </h3>
<button >Update Count</button>
</>
);
}
output :
Always write this useState statements write inside the function. if we write outside the function or component we give error.
let [state,setState] = useState(initialState); // demo
let [stateVariableName,setStateVariable] = useState(initialState); // demo
let [count,setCount] = useState(0); // example
example - Countbtn.jsx :
import { useState } from "react";
export default function Click(){
let [count,setCount]=useState(0);
function clickMe(){
// count += 1; // we can't write these it will not update in UI
setCount(count+1); // update value in count var.
console.log(count);
}
return(
<>
<h3>click count :{count} </h3> // pass value
<button onClick={clickMe}>Update Count</button> // pass function clickme.
</>
);
}
output :
Activity - 01 : Create like button
Like.jsx :
import { useState } from "react";
export default function Like(){ //create Like component
// here we create state variable name likeValue and it's update function name
setLikeValue , and initial value of likeValue = false.
// what is meaning of Toogle ?
let [likeValue,setLikeValue] = useState(false);
// than we create toogleLike function for update likeValue variable.
let toogleLike = ()=>{
// if likeValue = true than convert it value to False & viceversa, with
help of updater function name setLikeValue.
setLikeValue(!likeValue);
}
// than we define style of like button. create var name of likeStyle.
let likeStyle = {color : "red"};
return(
<>
<p onClick={toogleLike} style={likeStyle}> // apply function & style in para tag.
// if likeValue = true than show solid heart like button , if not than show
regular (only borderd) like button.
// we use like icon from FontAwasom website. link below.
{
likeValue ? (<i className="fa-solid fa-heart"></i>)
: (<i className="fa-regular fa-heart"></i>)
}
</p>
</>
); // than import this file into App.jsx and show output.
}
Toogle means if value is true than convert false & viceversa (True & false interchange).
output : (clicked like button)
Closure
Closure is a feature of JS where an inner function has access to the outer function's variables.
above figure if we call inner() only than we can use var b inside inner function. so this is a feature of javascript closure.
How Re-Render Works - 1
We use click btn to update count number for understand re-rendering.
Clickbtn.jsx :
import { useState } from "react";
export default function Click(){
let [count,setCount]=useState(0); // initialisation
console.log(`click component is re-render now. and count = ${count}`); // updated value.
function clickMe(){
setCount(count+1);
console.log(`value of count after count + 1 = ${count}`); // value not updated.
}
return(
<>
<h3>click count :{count} </h3>
<button onClick={clickMe}>Update Count</button>
</>
);
} // import in App.jsx
output :
First when click first time btn than count var value is not updated. it is updated before re-render the component. so that's why console is one step back.
Callback in setState function
setState is asynchronous (async) function. so when we depend in old value than we use callback into setState function.
Clickbtn.jsx :
import { useState } from "react";
export default function Click(){
let [count,setCount]=useState(0);
function clickMe(){
// we write double time but it works only one time.
setCount(count+1);
setCount(count+1);
}
return(
<>
<h3>click count :{count} </h3>
<button onClick={clickMe}>Update Count</button>
</>
);
}
// problem : when we click btn than it update only one time. not a double time.
so that's why we use callback into the setCount function.
solution :
import { useState } from "react";
export default function Click(){
let [count,setCount]=useState(0);
function clickMe(){
// we use callback and it run 2 times successsfully.
setCount((currVal)=>{ // 1st
return currVal +1;
});
setCount((currVal)=>{ // 2nd
return currVal +1;
});
}
return(
<>
<h3>click count :{count} </h3>
<button onClick={clickMe}>Update Count</button>
</>
);
}
output : when click btn than update value two times. run it.
How works Re-Render? - 2
Re-Render only ocuur when change the value of state variable. if value of state variable does not change than re-rendering not occur.
example :
import { useState } from "react";
export default function Click(){
let [count,setCount]=useState(0);
console.log("re-render");
function clickMe(){
setCount(15); // give fix value of count var = 25
}
return(
<>
<h3>click count :{count} </h3>
<button onClick={clickMe}>Update Count</button>
</>
);
}
output :
but, when we update or change this state var value than it re-render many times when we click many times btn. example :
import { useState } from "react";
export default function Click(){
let [count,setCount]=useState(0);
console.log(`re-render`);
function clickMe(){
setCount((currVal)=>{ // change value
return currVal +1;
});
}
return(
<>
<h3>click count :{count} </h3>
<button onClick={clickMe}>Update Count</button>
</>
);
}
output :
we also use function inside useState(). example :
import { useState } from "react";
function init(){
console.log("init was re-executed");
return 25;
}
export default function Click(){
let [count,setCount]=useState(init()); // initial value = 25
output : so we get many times statement : init was re-executed beacause of init()
but we write init only like this. so we don't call many times init function . it run only one time when initialization ok..
let [count,setCount]=useState(init);
output : (only one time show init re-executed)
Object & State
We use object into useState(). if we write multiple state var than code become so long, that`s why we create object and in this object we create multiple state variables. so code become cool & preety.
here we create demo app . into demo app we create 4 buttons to update click count of perticular color click update. image show in below. in this activity we show multiple problems and we solve it properly. so let start.
Click.jsx :
import { useState } from "react";
export default function Click(){
// here we create state object name "moves". in moves there are 4 properties
which is act as state variables. properties is blue,red,green & yellow. and it`s
initial value = 0. we use "setMoves" to updates it`s value.
let [moves,setMoves]=useState({blue:0,red:0,green:0,yellow:0});
// create updateBlue function it incress value + 1 by click "update blue count" btn.
function updateBlue(){
moves.blue += 1; // update blue value by one
console.log(`moves.blue = ${moves.blue}`); // print after update
setMoves( moves); // change in moves object
}
return(
<>
<h3>blue count :{moves.blue} </h3>
<button onClick={updateBlue}>Update blue Count</button>
</>
);
} // import into App.jsx
output :
Problem : above img blue value update but UI not change. it means state object not change that's why it can't re-render.
why ?
Solution : in object & Array in JS, when we change it`s elements & properties than value of these properties will be change, but object remains same. it means object not change that`s why address of object not change and than state not change and re-render not possible. so if we create copy of object than address will change and state will change and re-render done with help of JS Spreade.
import { useState } from "react";
export default function Click(){
let [moves,setMoves]=useState({blue:0,red:0,green:0,yellow:0});
function updateBlue(){
moves.blue += 1;
console.log(`moves.blue = ${moves.blue}`);
// we write Spreade to create object copy. than react understand ki kaik change
thayu che jethi re-render thashe. ok. spread syntax : {...<object-name>}
setMoves( {...moves});
}
return(
<>
<h3>blue count :{moves.blue} </h3>
<button onClick={updateBlue}>Update blue Count</button>
</>
);
}
output :
so count change in UI. we also write like these......👇
function updateBlue(){
console.log(`moves.blue = ${moves.blue}`);
setMoves( {...moves, blue: moves.blue +1});
// into setMoves change value of blue property and create copy of moves object.
}
final code of activity or demo app :
import { useState } from "react";
export default function Click(){
let [moves,setMoves]=useState({blue:0,red:0,green:0,yellow:0});
function updateBlue(){
setMoves( {...moves, blue: moves.blue +1});
}
function updateYellow(){
setMoves( {...moves, yellow: moves.yellow +1});
}
function updateRed(){
setMoves( {...moves, red: moves.red +1});
}
function updateGreen(){
setMoves( {...moves, green: moves.green +1});
}
return(
<>
<p>blue count :{moves.blue} </p>
<button onClick={updateBlue} style={{backgroundColor:"blue"}}>Update blue Count</button>
<p>yellow count :{moves.yellow} </p>
<button onClick={updateYellow} style={{backgroundColor:"yellow" , color:"black"}} >Update yellow Count</button>
<p>green count :{moves.green} </p>
<button onClick={updateGreen} style={{backgroundColor:"green"}}>Update green Count</button>
<p>red count :{moves.red} </p>
<button onClick={updateRed} style={{backgroundColor:"red"}}>Update red Count</button>
</>
);
}
output :
we also write like these :
setMoves( (previousMoves)=>{
return {...previousMoves,blue:previousMoves.blue+1};
}
Array & State
same like this we apply on array.
Arr.jsx :
import { useState } from "react";
export default function Click(){
let [arr,setArr] = useState(["helo"]); // create state array name "arr" and
initial value is "helo". helo is 1st
element of arr array.
function addEle(){
arr.push('ele..'); // add "ele.." element when click btn
setArr(arr); // add change into arr
console.log(arr) // print into console
}
return(
<>
<p>Arr elemets : {arr}</p> // print in UI
<button onClick={addEle}>add ele</button>
</>
);
}
output : ( problem : UI not change beacause, arr state not change, only arr element change, not chage whole arr.)
solution : create arr copy with JS Spread. than state will be change & re-render occur.
import { useState } from "react";
export default function Click(){
let [arr,setArr] = useState(["helo"]);
function addEle(){
setArr([...arr,"ele.."]); // create copy & push "ele.."
console.log(arr)
}
return(
<>
<p>Arr elemets : {arr}</p>
<button onClick={addEle}>add ele</button>
</>
);
}
output :
ok problem solve with Sprad... we also write like this :
function addEle(){
setArr((previousArr)=>{
return [...previousArr,"ele.."]; // [] for array , {} for object
});
console.log(arr)
}
Activity - 02 : Todo
import { useState } from "react";
import { v4 as uuidv4 } from 'uuid';
export default function Click() {
let [todos, setTodos] = useState([{task : "sample",id:uuidv4(),isDone : false}]);
let [newTodo, setNewTodo] = useState("");
let updateTodoArr = () => {
setTodos((prevTodo)=>{ return [...prevTodo, {task : newTodo,id:uuidv4(),
isDone : false}]});
setNewTodo("");
}
let updateTodoValue = (event) => {
setNewTodo(event.target.value);
}
let deleteTodo = (id)=>{
setTodos(todos.filter((todo)=>todo.id != id));
}
let upperCaseAll = ()=>{
setTodos((prevTodo)=>(
prevTodo.map((todo)=>{
return {
...todo,
task : todo.task.toUpperCase(),
}
})
))
}
let upperTodo = (id)=>{
setTodos((prevTodo)=>(
prevTodo.map((todo)=>{
if(todo.id === id){
return {
...todo,
task : todo.task.toUpperCase(),
}
} else{
return todo;
}
})
))
}
let todoDone = (id)=>{
setTodos((prevTodo)=>(
prevTodo.map((todo)=>{
if(todo.id === id){
return {
...todo,
isDone : todo.isDone = true,
}
} else{
return todo;
}
})
))
}
return (
<>
<input type="text" onChange={updateTodoValue} value={newTodo}
placeholder="Enter task" />
<br />
<button onClick={updateTodoArr}>Add</button>
<hr />
<h3>Todo all Tasks</h3>
<br />
<ul>
{
todos.map((todo) => (
<>
<li key={todo.id} style={todo.isDone ?
{textDecorationLine:"line-through"} : {}}>{todo.task}</li>
<button onClick={()=>{deleteTodo(todo.id)}}>
delete</button>
<button onClick={()=>{upperTodo(todo.id)}}>
uppercase one</button>
<button onClick={()=>{todoDone(todo.id)}}>
isdone one</button>
</>
))
}
</ul>
<br /><br />
<button onClick={upperCaseAll}>upper all</button>
</>
);
}
output :
In Reaact inside Array, we use & avoid :
Activity - 03 : Lottery Game
In lottery game we show 3 numbers , if sum of three num is 15 than you won lottery. In this activity we write two methods of this game. first one is simple normal (boat) method and second is component structure method (pro). code will be same but in different component.
Without Component Decomposition (boat)
Lottery.jsx :
import { useState } from "react";
import { getRendom,sum } from "./helper";
export default function Lottery() {
let [ticket,setTicket] = useState(getRendom(3));
let isWinn = sum(ticket) === 15;
let buyTicket = ()=>{
setTicket(getRendom(3));
}
return (
<>
<h2>Lottery game !</h2>
<br />
<div>
<span>{ticket[0]}</span>
<span>{ticket[1]}</span>
<span>{ticket[2]}</span>
</div>
<br />
<button onClick={buyTicket}>Buy new ticket</button>
<br /><br />
<h3>{isWinn && "Congrate"}</h3>
</>
);
}
// import into App.jsx
helper.js :
function getRendom(n) {
let arr = new Array(n);
for (let i = 0; i < n; i++) {
arr[i] = Math.floor(Math.random() * 10);
}
return arr;
}
function sum(arr) {
return arr.reduce((sum, curr) => sum + curr, 0);
}
export { getRendom, sum };
here codesandbox :
With Component Decomposition (pro)
Component Types :
1. Logical 2. Presentational
above diagram we make different components for lottery game. we make sure also in componnents where is state , props , events . these three components must sure .
TicketNum.jsx :
/* eslint-disable react/prop-types */
import "./TicketNum.css";
export default function TicketNum ({num}){ // this prop will use in the Ticket.jsx
return <span className="TicketNum">{num}</span>;
}
Ticket.jsx :
import TicketNum from "./TicketNum";
import './Ticket.css'
export default function Ticket({ticket}){ // create prop name : ticket (it is array)
return (
<>
<div className="Ticket">
{
ticket.map( // use map function to dispaly all numbers from the ticket array
(num,index)=>(
<TicketNum num={num} key={index}/> // use ticketnum and pass it's prop num
)
)
}
</div>
</>
)
}
Lottery.jsx :
import { useState } from "react";
import { getRendom,sum } from "./helper";
import Ticket from "./Ticket";
export default function Lottery({n,winningSum}) { // create two props n & winningSum
let [ticket,setTicket] = useState(getRendom(n));
let isWinn = sum(ticket) === winningSum;
let buyTicket = ()=>{
setTicket(getRendom(n));
}
return (
<>
<h2>Lottery game !</h2>
<br />
<Ticket ticket={ticket}/>
<br />
<button onClick={buyTicket}>Buy new ticket</button>
<br /><br />
<h3>{isWinn && "Congrate"}</h3>
</>
);
}
App.jsx ;
/* eslint-disable no-unused-vars */
import './App.css'
import Lottery from './Lottery';
// import Ticket from './Ticket';
function App() {
return (
<>
<Lottery n={2} winningSum={8}/> // pass it's props
<Lottery n={2} winningSum={8}/>
</>
);
}
export default App;
here we do it second method to pass function as props. and we change over winning condition according to requirement to client.
App.jsx :
/* eslint-disable no-unused-vars */
import './App.css'
import Lottery from './Lottery';
import { sum } from './helper';
// import Ticket from './Ticket';
function App() {
let winCondition = (ticket)=>{
return sum(ticket) === 15; // we can change this condition and apply other condition like
// return ticket.every((num)=> num === ticket[0]); // if all num same == win ok.
}
return (
<>
{/* <Lottery n={2} winningSum={8}/>
<Lottery n={2} winningSum={8}/> */
<Lottery n={2} winCondition={winCondition}/>
}
</>
);
}
export default App;
Lottery.jsx :
import { useState } from "react";
import { getRendom,sum } from "./helper";
import Ticket from "./Ticket";
export default function Lottery({n,winCondition}) { // function as props
let [ticket,setTicket] = useState(getRendom(n));
let isWinn = winCondition(ticket);
let buyTicket = ()=>{
setTicket(getRendom(n));
}
return (
<>
<h2>Lottery game !</h2>
<br />
<Ticket ticket={ticket}/>
<br />
<button onClick={buyTicket}>Buy new ticket</button>
<br /><br />
<h3>{isWinn && "Congrate"}</h3>
</>
);
}
Forms in React
now we create Form.jsx file :
import { useState } from "react"
export default function Form(){
// we create a state var name of fullName and it's initial value is hiiii.
let [fullName,setFullName] = useState("hiiii");
return (<>
<form action="">
// we use state var as value in input element. and show output .
<input type="text" id="name" value={fullName} />
<button>submit</button>
</form>
</>) // output : we can not change this initial value.
}
than we use onChange attribute into the input. into the onchange we update the state var.
import { useState } from "react"
export default function Form(){
let [fullName,setFullName] = useState("hiiii");
const changeValue = (event)=>{
// console.log(event.target.value); // please know the event object.
setFullName(event.target.value); // update it value
}
return (<>
<form action="">
// onChange implemented. <input type="text" id="name" value={fullName} onChange={changeValue} />
<button>submit</button>
</form>
</>)
}
we use labels in form. in label element we generally use for attribute for match the id to input element. but in react we use javascript, and in js for is reserve keyword (for loop). that's why we do not use attribute name for . that's why we use "htmlFor".
Form.jsx :
import { useState } from "react"
export default function Form(){
let [fullName,setFullName] = useState();
const changeValue = (event)=>{
console.log(event.target.value);
setFullName(event.target.value);
}
return (<>
<form action=""> // don't use for , use htmlFor ok....
<label htmlFor="hello">Enter Full Name</label>
<input type="text" id="hello" value={fullName} onChange={changeValue} />
<button>submit</button>
</form>
</>)
}
but in console window, we show the for, not htmlFor , because JSX is directly convert. ok.
Handling Multiple Inputs
In Form we have a lot of inputs, so we can write state var for each and every input & it's set functions. but it is so long process. that's why in react we write a state object for multiple inputs & we update set function only one time. like this.
import { useState } from "react"
export default function Form(){
// 1. we should not write state var for all input.
// let [fullName,setFullName] = useState();
// let [username,setUserName] = useState();
// let [password,setPassword] = useState();
// 2. that's why we create state object name of formData, into this we create
three properties name of fullName,username & password. this name should
be same to the input "name" attribute value. because we find name in nwxt step. okokok
let [formData,setFormData] = useState({
fullName : "",
username: "",
password:"",
})
// if we write all set functions and change it's value than it take so long time.
// const changeValue = (event)=>{
// console.log(event.target.value);
// setFullName(event.target.value);
// setFullName(event.target.value);
// setFullName(event.target.value);
// }
// so , we write only single and common function and set it's value
const handleInputChange = (event)=>{
let fieldName = event.target.name; // for find which input element are trigger.
let newValue = event.target.value; // access vlaue for input element
setFormData((currData)=>{
// return copy of object & set event.target.name = event.targeet.value
return {...currData,[fieldName]:newValue}
})
}
const handleSubmit = (event)=>{ // for button
event.preventDefault(); // to prevent default action of form element.
console.log(formData); // print forData
setFormData({ // set to empty when click button
fullName : "",
username: "",
password:"",
})
}
return (<>
<form action="">
// give value like this beacause it's object. (formData.----) right,okok
// name attribute value same as object property name beacause we find
event.target.name , that's why we type same as well as.
// id should be same name as htmlfor value.
<label htmlFor="fullName">Enter Full Name</label>
<input type="text" id="fullName" value={formData.fullName} name="fullName" onChange={handleInputChange} /><br /><br />
<label htmlFor="username">Enter Username</label>
<input type="text" id="username" value={formData.username} name="username" onChange={handleInputChange} /><br /><br />
<label htmlFor="password">Enter Your Password</label>
<input type="text" id="password" value={formData.password} name="password" onChange={handleInputChange} />
<button onClick={handleSubmit}>submit</button>
</form>
</>)
}
useEffect()
this is like side-effect function in react, run at the time of rendering process.
import { useState,useEffect } from "react" // import useEffect
export default function Click(){
let [count,setCount] = useState(5); // defalut value set : 5
const incCount =()=>{
setCount((currCount)=>
currCount+1
);
}
// useEffect(setup,dependencies) // we use normal function into write console.log("....");useEffect(()=>{
console.log("this is side effect")
})
return(<>
<h3>{count}</h3> // print count var
<br />
<button onClick={incCount}>+1</button> //incress count +1
</>)
}
output :
Dependences in useEffect()
into the dependences we write which var name those change than useEffect call on this only. ex :
import { useState,useEffect } from "react"
export default function Click(){
let [countx,setCountx] = useState(5);
let [county,setCounty] = useState(5);
const incCountx =()=>{
setCountx((currCount)=>
currCount+1
);
}
const incCounty =()=>{
setCounty((currCount)=>
currCount+1
);
}
//we pass array, into array we pass var name [var1,var2,...]useEffect(()=>{
console.log("this is side effect")
},[countx]) // when countx value change then useEffect work otherwise not
// [countx,county] --> both var are dependences
// [single var]
// [] --> empty
// check it
// if we pass empty arr than only one time useEffect work , than it not work.
return(<>
<h3>{countx}</h3>
<br />
<button onClick={incCountx}>+1</button>
<br />
<h3>{county}</h3>
<br />
<button onClick={incCounty}>+1</button>
</>)
}
Material UI is an open-source React component library that implements Google's Material Design.
installation :
npm install @mui/material @emotion/react @emotion/styled
npm install @fontsource/roboto --> for font
Material UI uses Emotion as its default styling engine.
it's like bootstrap. first import component and use it. example for button :
import { useState } from 'react'
import Button from '@mui/material/Button'; // first import pre-built component
function App() {
return (
<>
<Button variant="contained" color="success"> // use it with various attri..
Success
</Button>
</>
)
}
export default App
so use buttons ,alerts ,checkbox , cards ,etc like bootstrap
so.