Reagovat políčko: události.preventDefault() přestávky onChange funkci - proč?

0

Otázka

Právě jsem našel zatoulaný event.preventDefault() to rvalo políčka' onChange handler:

import { Component } from 'react';

class App extends Component {
  constructor(props) {
    super(props)
    this.state = {
      accepted: false
    }
  }

  changeChecked = (event) => {
    this.setState((state) => ({
      accepted : !state.accepted
    }));
    event.preventDefault(); // <- this very bad
  }

  render() {
    return (
      <input
        type="checkbox" 
        onChange={this.changeChecked}
        checked={this.state.accepted}
      />
    );
  }
}

export default App;

Výsledné chování je správně aktualizován stav na první kliknutí, ale políčko pouze změny v jeho "kontrolovat" vzhled na příští překreslil, např. druhé kliknutí.

Proč je, že? Není to bod kontrolované součásti pracovat nezávisle na prohlížeči událostí?

Někdo vysvětloval mi to bude určitě zmírnit bolest hodin strávených vařením dolů můj složitý případ použití. Děkuji!!!

Aktualizace: Zde je rychlý Codepen příklad prokazující zvláštní chování. Jsem součástí 'unprevented políčko' a jeden s zabráněno onClick událost jako srovnání. Všimněte si, jak ten se brání onChange přepne svůj vzhled k jeho aktuálního stavu, jakmile jsem klepněte na jiné políčko.

2

Nejlepší odpověď

2

Políčka se chovají trochu jinak. Jak pravděpodobně víte, typický use case pro preventDefault() je onSubmit() funkce formulář, kde budete dělat svůj vlastní AJAX volání, a proto chtějí, aby se zabránilo výchozí odeslání formuláře. Ale s checkboxe (a většinu vstupů), tam je trochu více zapojit.

Kontroluje atribut

Na MDN, checked atribut je "Boolean atribut, který označuje, zda je či není toto políčko zaškrtnuto ve výchozím nastavení (když se stránka načte). To není uvedeno, zda toto pole je v současné době kontrolována: pokud políčko je stát se změní, tento obsah atributu neodráží změny." V legrační způsob, jak, pak, tam je rozpor mezi checked atribut, a to, zda je nebo není stav vstup je kontrolován nebo ne. Když přijde na to Reagovat, na každé překreslil, checked atribut bude odrážet současný stav, ale je to stále jen výchozí hodnotu v tom smyslu, že vstup má být nově vydány, a nikoliv manipulovat od státu loni změnilo.

Nativní eventListener pro <input type="checkbox" />

Také, aniž by se příliš mimo trať, v případě, že nativně změní stav na vstupní políčko je ve skutečnosti click události, ne change akce. Pokud jste byli, aby nepořádek s posluchači a hodnoty políčka, input v prohlížeči js konzole, viděl by jste můžete manipulovat způsobem, že toto políčko není zaškrtnuto, ale hodnoty uzlu říkají jinak.

Možné řešení

Na základě výše uvedeného, v tomto případě vám nechci aby se zabránilo výchozí chování, protože výchozí chování na change případě není v rozporu s tím, co chcete dělat (a z nějakého důvodu brání to způsobuje problémy). Ve skutečnosti, v Reagovat docs příklady, zjistíte, že nepoužívají preventDefault() při aktualizaci stavu na kontrolované součásti. Přál bych si mít lepší pochopení , proč přesně přidávání preventDefault() změnit rutiny pro vstupy způsobuje problémy, jako je tento, ale doufejme, že těchto několik malé kousky, dát trochu více jasnosti.

2021-11-19 05:02:26

Díky, Dave. Skutečnost, že checked atribut pouze popisuje výchozí stav o načítání stránky je dobré vést. Pořád nemůžu zabalit hlavu kolem skutečného chování (aktualizace vzhled na druhé kliknutí - viz můj Codepen příklad výše), ale myslím, že důvody pro to jsou pohřbeny hluboko v propojení reagovat a prohlížeč událostí. Možná kámen lepší vlevo na kameni. ;)
gl03
0

Zkuste event.preventDefault() výše this.setState line.

2021-11-18 17:43:44

děkuji vám za divoký odhad, ale to nedělá rozdíl. c.f. MDN: "Volání preventDefault() během jakékoliv fáze toku události zruší událostí, což znamená, že výchozí akcí obvykle přijatá plnění v důsledku události nedojde."
gl03

V jiných jazycích

Tato stránka je v jiných jazycích

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................