Understanding Events
You don't want components to have state. But. Occasionally, they need some states. How do you make them react to events.
- Pulling external HTML fragments and render those into the DOM?
Standard skeleton:
var React = require('react');
var App = React.createClass({
render () {
return (
<div>
</div>
)
}
});
// React.render(<App/>, document.body);
// to add a simple event:
var button = document.createElement('button');
button.onclick = () => alert('hi');
document.body.appendChild(button);
Says, that events in the DOM are declarative. To do the same in React:
var React = require('react');
var alertStuff = () => {
alert("stuff");
}
var App = React.createClass({
render () {
return (
<div>
// need to camelcase the eventname
<button onClick={alertStuff}>hi</button>
</div>
)
}
});
React.render(<App/>, document.body);
You also have onMouseEnter
, which is not in the actual DOM events spec.What if we want to pass different arguments to the click handler? We have to buttons and want to pass different parameters to
alertSftuff
.
var React = require('react');
// 2. ++++ adds msg variable
var alertStuff = (msg) => {
alert(msg);
}
var App = React.createClass({
render () {
return (
<div>
// 3. ++++ need to use `bind`
<button onClick={alertStuff.bind(this, 'hi')}>hi</button>
// 1. ++++ adds second button
// 4. ++++ adds the `bind` method
<button onClick={alertStuff.bind(this, 'bye')}>bye</button>
</div>
)
}
});
React.render(<App/>, document.body);
You can also pass user
in the bind
: alertStuff.bind(this, user.info)
- Isn't it bad to add event handlers declaratively?- before, long time ago, we used to do events like this:
<button onclick="alertStuff('hi')">bad pattern</button>
This was considered to be an anti-pattern. Why? One advantage is that it's clear for the developer what will happen.
The downside is that
alertStuff
has to be a global variable. We don't have these secondary effects anymore in the above React pattern. The handler can be scoped now, like above.
- Isn't binding arrow functions bad?- There's no other way to bind (add) an argument. He tries to avoid using
this
, but React needs it in a lot of places.We could just use
<button onClick={alertStuff.bind(null, 'bye')}>bye</button>
- We're not really inserting HTML fragments. We're creating functions, and React updates the DOM.
We can put the alertStuff
inside component. This is more common pattern.
var React = require('react');
// 1. ++-- moves this down
var alertStuff = (msg) => {
alert(msg);
}
var App = React.createClass({
// 2. ++++ adds it here
alertStuff (msg) {
alert(msg);
},
render () {
return (
<div>
// ++-- change to this.alertStuff
<button onClick={this.alertStuff.bind(this, 'hi')}>hi</button>
<button onClick={this.alertStuff.bind(this, 'bye')}>bye</button>
</div>
)
}
});
React.render(<App/>, document.body);