No site found for btvca-curriculum.herokuapp.com; using Bootcamp content.
Responding to Events
- Event handling in React is similar to handling DOM events
- Handler functions can be passed as Props
- Event names are camelCased i.e.
onClick
,onSubmit
,onHover
<!-- HTML Event Handler -->
<button onclick="handleData()">
Submit Data
</button>
/* React Event Handler */
<button onClick={handleData}>
Submit Data
</button>
Preventing Default Behavior
- Calling
event.preventDefault()
must be done in the handler
function Link () {
function handleClick(event) {
event.preventDefault();
doSomethingWithTarget(event);
}
return (
<a href="#" onClick={handleClick}>
Click Me React
</a>
);
}
React Events are SyntheticEvents
- Events are not real DOM events
- They are captured by React and replaced with SyntheticEvent
- SyntheticEvents behave the same accross all Browsers, unlike DOM Events
Propery | Return Type |
---|---|
bubbles | boolean |
cancelable | boolean |
currentTarget | DOMEventTarget |
defaultPrevented | boolean |
eventPhase | number |
isTrusted | boolean |
nativeEvent | DOMEvent |
preventDefault() | void |
isDefaultPrevented() | boolean |
stopPropagation() | void |
isPropagationStopped() | boolean |
target | DOMEventTarget |
timeStamp | number |
type | string |
Events are Nullified after Handling
- After the event handler function is called the event is set to Null
- This is because SyntheticEvents are reused for other Events
- Do not handle events using Async functions, unless calling
event.persist()
first
Usual Behavior
function onClick(event) {
console.log(event); // => nullified object.
console.log(event.type); // => "click"
const eventType = event.type; // => "click"
setTimeout(function() {
console.log(event.type); // => null
console.log(eventType); // => "click"
}, 0);
// Won't work.
// this.state.clickEvent will only contain null values.
this.setState({clickEvent: event});
// You can still export event properties.
this.setState({eventType: event.type});
}
Binding Event Handlers
- JavaScript classes do not by default
bind
thethis
in ES6 Classes - Binding is a normal JavaScript behavior and is very confusing
- Either use
bind
in the constructor, or use an ES6 Arrow Function
class Toggle extends React.Component {
constructor (props) {
super(props);
this.state = { isToggleOn: true };
// Binding is necessary to make `this` work in the callback
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(prevState => ({
isToggleOn: !prevState.isToggleOn
}));
}
render() {
return (
<button onClick={this.handleClick}>
{this.state.isToggleOn ? true : false}
</button>
);
}
}
ReactDOM.render(
<Toggle />,
document.getElementById('root')
);
Binding Event Handlers - Arrow Functions
- Class constructor with
this.function = this.function.bind(this)
are verbose - Rewrite the Class property as an arrow function as below
- Only available when transformed via Babel using
create-react-app
or other
class LoggingButton extends React.Component {
// This syntax ensures `this` is bound within handleClick.
// Warning: this is *experimental* syntax.
constructor (props) {
super(props)
this.state = { isToggleOn: true }
}
handleClick = () => {
this.setState(prevState => ({
isToggleOn: !prevState.isToggleOn
}));
}
render() {
return (
<button onClick={this.handleClick}>
{this.state.isToggleOn ? true : false}
</button>
);
}
}
Lab: Logging in
Let's create a simple login page! Create a new React project that:
- Displays a button that says "please log in" when you first visit the page
- When the button is clicked
- the button should disapear
- and the page should display "Welcome! This is React."