06. React - manipulace s událostmi

14.02.2019 Programování #react #events

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 falseaby 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í .