You are on page 1of 6

props- data & functions which is to be shared with the other components

props are immutable

happens between parent to the child

child to parent communication is also possible - event handling (callbacks)

state : similiar to props


not used for sharing the data between components but to hold the state of the
components

is mutable

step 1:

step 2:

state vs props:
================

this.setState - to change state -- this is async

this has 2nd arg which is callback

this.setState({a:9},()=>{console.log('hi')})

step 3 : iterate and print

import React,{Component} from "react";


import "./style.css";

export default class App extends Component {


constructor(){
super();
this.state={
monsters:[
{name:'IronMan'},
{name:'SpiderMan'},
{name:'Captain America'},
{name:'Hulk'}
]
}
}
render(){
return (
<div className="App">
{this.state.monsters.map(mon=><h1>{mon.name}</h1>)}
</div>
);
}
}

step 4: assign keys using index and then using user defined id

so change the data harded as below


constructor(){
super();
this.state={
monsters:[
{name:'IronMan',id:1234},
{name:'SpiderMan',id:1334},
{name:'Captain America',id:2335},
{name:'Hulk',id:9264}
]
}
}

and

in iteration

<div className="App">
{this.state.monsters.map((mon,i)=><h1>{mon.id} {mon.name}</h1>)}
</div>

or

<div className="App">
{this.state.monsters.map((mon)=><h1 key={mon.id}>{mon.id} {mon.name}</h1>)}
</div>

step 5: life cycle basic method and external server or api endpoints

get data and iterate data from it in componentdidmount method

Step 6:

including bootstrap and creating multiple components

create folder - card-list


create js file with name card-list.js

then export it and import in app.js as shown below

in card-list.js
================

import React,{Component} from "react";

const cardList=(props)=>{
console.log(props); //to know what is props
return (<div>hello</div>);
}

export default cardList;

in app.js:
============
<div className="App">
<CardList/>
</div>
step 7:

pass the api data to card-list component thru props and move the iteration code to
it

or pass it as children of component

in app.js:
===========
<CardList>
{this.state.heros.map((mon,i)=><h1 key={mon.id}>{mon.id} {mon.name}</h1>)}
</CardList>

in card-list.js
=================

const cardList=(props)=>{
console.log(props); //to kknow what is props
return (<div className='card-list'>{props.children}</div>);
}

Note : add grid css template code- create a css file

.card-list{
width:85vw;
margin:0 auto;
display : grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-gap: 20px;
}

step 8: props drilling - pass the data heros to card component which will be sub
component of card-list component

create a folder card and create a js file with name card.js & card.scss too

in card.js
===========

import React,{Component} from "react";

const Card=(props)=>{
console.log(props); //to kknow what is props
return (<div >{props.hero.id}{props.hero.name}</div>);
}

export default Card;

in card-list.js - modify as below


=================================
import React,{Component} from "react";
import './card-list.css';
import Card from '../card/card'
export default class CardList extends Component {
constructor(props){
super(props);
}
render(){
console.log(this.props);
return (

<div className='card-list'>
{
this.props.data.map((mon)=>( <Card key={mon.id} hero={mon}/>))
}
</div>
);
}
}

in app.js - modify as below


============================
return (
<div className="App">

<CardList data={this.state.heros}/>

</div>
);

Step 9: add css for card


=========================

create a card.css in card folder as below

.card-container {
display: flex;
flex-direction: column;
background-color: #95dada;
border: 1px solid grey;
border-radius: 5px;
padding: 25px;
cursor: pointer;
-moz-osx-font-smoothing: grayscale;
backface-visibility: hidden;
transform: translateZ(0);
transition: transform 0.25s ease-out;
}

.card-container:hover {
transform: scale(1.05);
}

step 10 : add images from below link dynamically


===================================================
https://robohash.org/1?set=set2

<div className='card-container' >


<img src={`https://robohash.org/${props.hero.id}?set=set2&size=140x140`}/>
<h1>{props.hero.name}</h1>
</div>);

when do we break them into many compoennts ?

it depends on

1. reusability - in any proj


2. state - who maintains state - generally parent
3. what are things to be changes when state changes = changes the tree graph
state triggers render() of each component
4. easy to test

we have filter the list of data:

we have add a component with name : Search component.js

in App.js:
============

create a search box and have some place holders

<input type='search' placeholder='search heros' onChange={e=>console.log(e)}/>

in above code , we have a ananymous function - captures synthetic events

synthetic are predefined wrapped by react api's

Change the above line as shown below to get value of char being typed

<input type='search' placeholder='search heros'


onChange={e=>console.log(e.target.value)}/>

assign the value typed to state variable, but before create a variable

Now create 2 temp variables one for filtered array and other for search value
inside render()

reason to create in render is every change of search field which is state var,
calls render
so that filter can happen and display the matched char list

const {heroTemp,searchData}=this.state; //make it work

const
filteredHero=this.state.heros.filter(m=>m.name.toLowerCase().includes(this.state.se
archFieldData.toLowerCase()));

and

<CardList data={filteredHero}/>

deploy in GIT :
===================================================================================
=====================
to show react virtual dom and its working from our hero app

do some modification

pass heros instead of filteredHero and comment fileteredHero var in render()

create a title variable, and set the state in on change event in search box, inside
setstate

this.state={
heros:[
{name:'IronMan',id:1234},
{name:'SpiderMan',id:1334},
{name:'Captain America',id:2335},
{name:'Hulk',id:9264}
],
searchFieldData:'',
title:''
}

<input type='search' placeholder='search heros'


onChange={e=>this.setState({searchFieldData:e.target.value,title:e.target.value})}/
>

<h1> {this.state.title}</h1>

use rendering in F12 dev tool and paint flashing


===================================================================================
=====================
Indepth of setState :

setState is async,
constructor(){
super();
this.state={
status:''
}
}

this.setState((prevState,prevProps)={console.log(prevState.status)},
()=>{console.log('callback '+this.state.status)})

You might also like