Manipulace s událostmi v Reactu je podobné jako v klasickém DOM.
- Události jsou v Reactu pojmenovány pomocí camelCase míst malých písmen.
- S funkcí JSX se předává funkce jako obslužnou rutinu události, nikoliv řetězec.
Příklad v HTML:
<button onclick="activateLasers()">
Activate Lasers
</button>
je mírně odlišný v Reactu:
<button onClick={activateLasers}>
Activate Lasers
</button>
Dalším rozdílem je, že se nemůže vrácet hodnota false
, aby se zabránilo výchozímu chování v Reactu. Musíte výslovně volat preventDefault
. Například v čistým HTML, aby se zabránilo otevření odkazu jako nové stránky, můžete psát:
<a href="#" onclick="console.log('The link was clicked.'); return false">
Click me
</a>
V Reactu by se dalo napsat:
function ActionLink() {
function handleClick(e) {
e.preventDefault();
console.log('The link was clicked.');
}
return (
<a href="#" onClick={handleClick}>
Click me
</a>
);
}
Zde je e
syntetická událost. React definuje tyto události podle specifikace W3C. Tím nevzniká problém s kompatibilitou prohlížečů.
Při použití Reactu byste obecně neměli volat addEventListener
přidávat listener prvky do DOM po jeho vytvoření. Místo toho pouze poskytněte listener, když je element zpočátku vykreslen.
Při definování součásti pomocí třídy ES6 je společným vzorem pro obslužnou rutinu událostí metoda ve třídě. Tato Toggle
součást například vykresluje tlačítko, které umožňuje uživateli přepínat mezi stavy "ON" a "OFF":
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true};
// This binding is necessary to make `this` work in the callback
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(state => ({
isToggleOn: !state.isToggleOn
}));
}
render() {
return (
<button onClick={this.handleClick}>
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
);
}
}
ReactDOM.render(
<Toggle />,
document.getElementById('root')
);
Ohledně významu this
musíte být v JSX opatrní. Ve třídě JavaScriptu není klasifikační metoda ve výchozím nastavení vázána. Pokud ji zapomenete svázat this.handleClick
a předat to onClick
, this
bude undefined
, když je funkce skutečně volána.
Toto není specifické chování Reactu. Je to součást jak pracují funkce v javaScriptu. Jestliže se odkazujeme na metodu bez (), například onClick={this.handleClick}
byste ji měli svázat.
Pokud používáte syntaxi experimentálních polí veřejné třídy, můžete pole tříd správně svázat zpětná volání:
class LoggingButton extends React.Component {
// This syntax ensures `this` is bound within handleClick.
// Warning: this is *experimental* syntax.
handleClick = () => {
console.log('this is:', this);
}
render() {
return (
<button onClick={this.handleClick}>
Click me
</button>
);
}
}
Pokud nepoužíváte syntaxi polí tříd, můžete v operačním systému použít funkci šipky:
class LoggingButton extends React.Component {
handleClick() {
console.log('this is:', this);
}
render() {
// This syntax ensures `this` is bound within handleClick
return (
<button onClick={(e) => this.handleClick(e)}>
Click me
</button>
);
}
}
Problém s touto syntaxí je, že při každém vykreslování LoggingButton
se vytváří jiné zpětné volání. Ve většině případů je to v pořádku. Je-li však toto zpětné volání předáno jako prvek pro spuštění komponent, mohou tyto součásti provádět dodatečné vykreslování. Obecně doporučujeme v konstruktoru zavázat vazbu nebo použít syntaxi polí tříd, abychom se vyhnuli tomuto druhu výkonu.
Předávání argumentů
Uvnitř smyčky je běžné, že chcete předávat další parametr obsluze událostí. Pokud je například id
ID řádku, bude fungovat jedna z následujících možností:
<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>
Výše uvedené dva řádky jsou ekvivalentní a používají šipkové funkce a Function.prototype.bind
resp.
V obou případech bude argument e
reprezentující událost React předán jako druhý argument za ID. Funkcí se šipkami musíme předat výslovně, ale bind
další argumenty se automaticky předávají .