What
Event occur when a user or the browser manipulate a page.
For Ex →
Page Loading
, clicking a Button
, Pressing any Key
, Closing a window
These all are the events.
We as a developer use these Events to manipulate things in the site.
In the Case of React Events, they are not actually the DOM Events
they are called Synthetic Events
.
Synthetic Events
→ These are the Wrappers that React uses to standardise event functionality across browser.
But what is the need of Synthetic Events ??
- Actually Events are not the part of Core JavaScript , they come from each browser’s JavaScript API , means Each browser will handle them differently.
- So in React we have the Synthetic Events which makes the consistency across all the browser.
How
So we have many types of the Synthetic Events including keyboard events, form events , mouse events etc.
Some of them are :
onClick
onContextMenu
onDoubleClick
onDrag
onDragEnd
onDragEnter
onDragExit
onDragLeave
onDragOver
onDragStart
onDrop
onMouseDown
onMouseEnter
onMouseLeave
onMouseMove
onMouseOut
onMouseOver
onMouseUp
For more visit this link :
Example →
-
when ever u try to hover on the
Smily
It will log a Proverb and if try to copy the text it will give u an alert
**App.js**
import './App.css';
import React, { Component } from 'react'
import CopyDemo from "./CopyDemo"
import Messenger from './Messenger';
class App extends Component {
render(){
return(
<div>
<Messenger/>
<CopyDemo />
</div>
)
}
}
export default App;
**CopyDemo.js**
import React, { Component } from 'react'
class CopyDemo extends Component {
constructor(props) {
super(props);
this.state={};
this.handleCopy = this.handleCopy.bind(this);
}
handleCopy(e){
console.log(e);
alert('Stop Copying Me')
}
render(){
return(
<div >
<div style={{margin: "31px auto",
width: "50%"}}>Try to Copy the Text Below 👇</div>
<div style={{textAlign: 'center',backgroundColor:'red',width:"50%",margin:"0 auto"}} onCopy={this.handleCopy}>
lorem ipsum dolor sit amet, consectetur adipiscing elit.lorem ipsum dolor sit amet lorem ipsum dolor sit amet, consectetur adipiscing elit.lorem ipsum dolor sit amet lorem ipsum dolor sit amet, consectetur adipiscing elit.lorem ipsum dolor sit amet lorem ipsum dolor sit amet, consectetur adipiscing elit.lorem ipsum dolor sit amet lorem ipsum dolor sit amet, consectetur adipiscing elit.lorem ipsum dolor sit amet lorem ipsum dolor sit amet, consectetur adipiscing elit.lorem ipsum dolor sit amet
</div>
</div>
);
}
}
export default CopyDemo;
**Messenger.js**
import React, { Component } from 'react'
class Messenger extends Component {
constructor(props) {
super(props);
this.handleMouseEnter = this.handleMouseEnter.bind(this);
}
handleMouseEnter(){
const messages = ["All good things come to an end"," A journey of a thousand miles begins with a single step"," Actions speak louder than words"," An apple a day keeps the doctor away"];
const rand = Math.floor(Math.random() * messages.length);
console.log(messages[rand]);
}
render() {
return(
<div className="App">
<h1>Proverbs 👇</h1>
<div onMouseEnter={this.handleMouseEnter} style={{width:"30px",backgroundColor:"Red",margin:"0 auto" }}>🙂</div>
</div>
)
}
}
export default Messenger;
Method Binding
class Messenger2 extends Component {
static defaultProps = {
messages: ["All good things come to an end"," A journey of a thousand miles begins with a single step"," Actions speak louder than words"," An apple a day keeps the doctor away"]
}
handleMouseEnter(){
console.log("THIS IS:", this) // undefined 😭
**const {messages} = this.props;**
const rand = Math.floor(Math.random() * messages.length);
console.log(messages[rand]);
}
render() {
return(
<div className="App">
<h1>Proverbs 👇</h1>
<div onMouseEnter={this.handleMouseEnter} style={{width:"30px",backgroundColor:"Red",margin:"0 auto" }}>🙂</div>
</div>
)
}
}
- If u try to run this , it will give an
TypeError
.
Also if we console.log the value of this
we will see the value of undefined.
Ways to fix this problem →
1) Use Inline BInd
→
Cons
- New Function is Created on every render.
- Like above we have Created a Function handleClick and bind it using inline-bind but when we check if they are equal or not so it return false , So this means that a New Function is created when it renders.
2 . Arrow Function
→
Pros →
- No mention of Bind!
Cons →
- Intent less clear
- new function created on every render.
3 . In the Constructor
→
- Only need to bind once!
4 . Bonus One →
handleClick = ()=>{
console.log("This is : ",this);
}
- This will also used to bind.
Method Binding with Arguments →
In the previous example our this.handleClick
didn’t take any argument.
To Pass the Argument we can write like this :
onClick={this.handleClick.bind(this,<argument_name>)}
OR
onClick={()=>{this.handleclick(argument_name)}}
When we are using the Arrow function we have to use the Curly braces while calling the function.
Passing Functions to the child Component →
Children are often not stateful, but they need to tell parent to change the state.
But how can we send the data back to the parent Component??
Data Flow
- A parent Component defines the Function.
- The function is passed as a prop to a child component.
- The child component invokes the prop.
- The parent function is called, usually setting new state.
- The parent component is re-rendered along with its children.
One way to pass the Function →
we have to make something like this whenever we click on the cross button the corresponding Number should Disappear.
Numlist.js
import React, { Component } from 'react'
import NumberItem from "./NumberItem"
class NumberList extends Component {
constructor(props) {
super(props);
this.state = {nums:[1,2,3,4,5]};
}
remove(num){
this.setState(st=>({
nums:st.nums.filter(n=> n!== num)
}));
}
render(){
let num = this.state.nums.map(n=>(
<NumberItem value={n} remove={this.remove.bind(this,n)}/>
));
console.log(num);
return(
<ul>{num}</ul>
);
}
}
export default NumberList;
In this we have passed the remove
function as props to the NumItem Component .
NumItem.js
import React, { Component } from 'react'
class NumberItem extends Component {
render(){
return(
<li>
{this.props.value}
<button onClick={this.props.remove}>X</button>
</li>
)
}
}
export default NumberItem;
This code works fine but as we remove the elements the Numlist
Component get Re-rendered and we are binding the method remove inline , So every time the component get rendered new function created.
To solve this we have to bind the method in the Constructor.
import React, { Component } from 'react'
import BetterNumberItem from "./BetterNumberitems"
class BetterNumberList extends Component {
constructor(props) {
super(props);
this.state = {nums:[1,2,3,4,5]};
**this.remove = this.remove.bind(this);**
}
remove(num){
console.log(num);
this.setState(st=>({
nums:st.nums.filter(n=> n!== num)
}));
}
render(){
let num = this.state.nums.map((n,idx)=>(
<BetterNumberItem value={n} remove={this.remove}/>
));
return(
<ul>{num}</ul>
);
}
}
export default BetterNumberList;
import React, { Component } from 'react'
class BetterNumberItem extends Component {
constructor(props){
super(props);
this.handleRemove = this.handleRemove.bind(this);
}
handleRemove(){
this.props.remove(this.props.value);
}
render(){
return(
<li>
{this.props.value}
<button onClick={this.handleRemove}>X</button>
</li>
)
}
}
export default BetterNumberItem;
Earlier we are passing the argument to the remove method but now we aren’t so if we just try to console.log what is passed to remove we got the events.
So we call handleRemove function and in that we call the remove function and pass the argument to it.
Naming Convention →
List and keys
- Keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array
and I have also learnt how to write the Functional Component
Day 10 Completed!!🥳