Istnieją tutaj trzy odpowiedzi, w zależności od wersji React, z którą jesteś (zmuszony) pracować (i) i od tego, czy chcesz użyć haków.
Po pierwsze:
Ważne jest, aby zrozumieć, w jaki sposób reagować prace, dzięki czemu można zrobić rzeczy właściwie (protip: to jest bardzo warto przebiegającej przez React samouczka ćwiczenia na React internetową Jest dobrze napisana i obejmuje wszystkie podstawy w taki sposób, że faktycznie wyjaśnia, jak to zrobić. rzeczy). „Prawidłowo” oznacza tutaj, że piszesz interfejs aplikacji, który jest renderowany w przeglądarce; cała praca interfejsu odbywa się w React, a nie w „tym, do czego jesteś przyzwyczajony, gdy piszesz stronę internetową” (dlatego aplikacje React to „aplikacje”, a nie „strony internetowe”).
Aplikacje React są renderowane na podstawie dwóch rzeczy:
- właściwości komponentu zadeklarowane przez którykolwiek z elementów nadrzędnych tworzy instancję tego składnika, którą element nadrzędny może modyfikować przez cały cykl życia, oraz
- własny stan wewnętrzny komponentu, który może modyfikować sam w całym cyklu życia.
To, czego wyraźnie nie robisz, gdy używasz React, to generowanie elementów HTML, a następnie ich używanie: kiedy mówisz Reactowi, aby <input>na przykład używał , np. Nie tworzysz elementu wejściowego HTML, mówisz Reactowi, aby utworzył obiekt wejściowy React które zdarza się renderować jako element wejściowy HTML, a obsługa zdarzeń patrzy na zdarzenia wejściowe elementu HTML, ale nie jest przez nie kontrolowana .
Korzystając z React, generujesz elementy interfejsu aplikacji, które prezentują użytkownikowi (często manipulowane) dane, a interakcja użytkownika zmienia stan składnika, co może spowodować ponowne przesłanie części interfejsu aplikacji w celu odzwierciedlenia nowego stanu. W tym modelu stan jest zawsze ostatecznym organem, a nie „dowolną biblioteką interfejsu użytkownika używaną do jego renderowania”, która w sieci WWW jest DOM przeglądarki. W tym modelu programowania DOM jest niemal ponownym przemyśleniem: jest to konkretna struktura interfejsu użytkownika, z której korzysta React.
W przypadku elementu wejściowego logika jest następująca:
- Wpisujesz element wejściowy,
- nic się nie dzieje z twoim elementem wejściowym, zdarzenie zostało przechwycone przez React i natychmiast zabite ,
- React przekazuje zdarzenie do funkcji skonfigurowanej do obsługi zdarzeń,
- ta funkcja może zaplanować aktualizację stanu,
- jeśli tak się stanie, React uruchomi tę aktualizację stanu (asynchronicznie!) i wyzwoli
renderpołączenie po aktualizacji, ale tylko jeśli aktualizacja stanu zmieni stan.
- dopiero po tym renderowaniu interfejs użytkownika pokaże, że „wpisałeś literę”.
Wszystko to dzieje się w ciągu kilku milisekund, jeśli nie mniej, więc wygląda na to, że wpisałeś się do elementu wejściowego w taki sam sposób, w jaki zwykłeś „po prostu używać elementu wejściowego na stronie”, ale to absolutnie nie to stało się.
Powiedziawszy to, jak uzyskać wartości z elementów w React:
Reaguj 15 i poniżej za pomocą ES5
Aby zrobić to poprawnie, twój komponent ma wartość stanu, która jest wyświetlana przez pole wejściowe, i możemy go zaktualizować, sprawiając, że element interfejsu użytkownika wysyła zdarzenia zmiany z powrotem do komponentu:
var Component = React.createClass({
getInitialState: function() {
return {
inputValue: ''
};
},
render: function() {
return (
//...
<input value={this.state.inputValue} onChange={this.updateInputValue}/>
//...
);
},
updateInputValue: function(evt) {
this.setState({
inputValue: evt.target.value
});
}
});
Tak powiemy React korzystać z updateInputValuefunkcji do obsługi interakcji użytkownika, użycie setStatezaplanować aktualizację stanu, oraz fakt, że rendersięga do this.state.inputValueśrodków, które gdy rerenders po aktualizacji stanu, użytkownik zobaczy tekst aktualizacji w oparciu o to, co wpisane.
uzupełnienie na podstawie komentarzy
Biorąc pod uwagę, że dane wejściowe interfejsu użytkownika reprezentują wartości stanu (zastanów się, co się stanie, jeśli użytkownik zamknie kartę w połowie, a karta zostanie przywrócona. Czy wszystkie te wartości, które wprowadzili, powinny zostać przywrócone? Jeśli tak, to stan). To może sprawić, że poczujesz, że duża forma potrzebuje dziesiątek, a nawet stu formularzy wejściowych, ale React polega na modelowaniu interfejsu użytkownika w sposób możliwy do utrzymania: nie masz 100 niezależnych pól wejściowych, masz grupy powiązanych danych wejściowych, więc przechwytujesz każdy zgrupuj w komponencie, a następnie utwórz formularz „master” jako zbiór grup.
MyForm:
render:
<PersonalData/>
<AppPreferences/>
<ThirdParty/>
...
Jest to również o wiele łatwiejsze w utrzymaniu niż gigantyczny pojedynczy komponent. Podziel grupy na komponenty z zachowaniem stanu, przy czym każdy komponent odpowiada tylko za śledzenie kilku pól wejściowych na raz.
Może się również wydawać, że napisanie całego kodu jest „kłopotliwe”, ale to fałszywa oszczędność: programiści, którzy nie są Tobą, w tym Ty, w rzeczywistości, czerpią ogromne korzyści z tego, że wszystkie te dane wejściowe są wyraźnie połączone, ponieważ znacznie ułatwia śledzenie ścieżek kodu. Zawsze możesz jednak zoptymalizować. Na przykład możesz napisać linker stanu
MyComponent = React.createClass({
getInitialState() {
return {
firstName: this.props.firstName || "",
lastName: this.props.lastName || ""
...: ...
...
}
},
componentWillMount() {
Object.keys(this.state).forEach(n => {
let fn = n + 'Changed';
this[fn] = evt => {
let update = {};
update[n] = evt.target.value;
this.setState(update);
});
});
},
render: function() {
return Object.keys(this.state).map(n => {
<input
key={n}
type="text"
value={this.state[n]}
onChange={this[n + 'Changed']}/>
});
}
});
Oczywiście istnieją ulepszone wersje tego, więc wejdź na https://npmjs.com i poszukaj rozwiązania łączenia stanu React, które najbardziej Ci się podoba. Open Source polega głównie na znalezieniu tego, co inni już zrobili, i wykorzystaniu tego zamiast pisania wszystkiego od zera.
React 16 (i 15.5 przejściowy) i „nowoczesny” JS
Począwszy od React 16 (i miękkiego startu z 15.5), createClasswywołanie nie jest już obsługiwane i należy użyć składni klas. Zmienia to dwie rzeczy: oczywistą składnię klas, ale także thispowiązanie kontekstu, które createClassmożna wykonać „za darmo”, więc aby upewnić się, że wszystko nadal działa, upewnij się, że używasz notacji „gruba strzałka” dla thiszachowania kontekstu w funkcjach onWhateverobsługi, takich jak onChangeużycie my w kod tutaj:
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
inputValue: ''
};
}
render() {
return (
//...
<input value={this.state.inputValue} onChange={evt => this.updateInputValue(evt)}/>
//...
);
},
updateInputValue(evt) {
this.setState({
inputValue: evt.target.value
});
}
});
Możliwe, że widziałeś, jak ludzie używają bindkonstruktora do wszystkich funkcji obsługi zdarzeń, takich jak:
constructor(props) {
super(props);
this.handler = this.handler.bind(this);
...
}
render() {
return (
...
<element onclick={this.handler}/>
...
);
}
Nie rób tego
Prawie za każdym razem, gdy używasz bind, obowiązuje przysłowiowe „robisz to źle”. Twoja klasa już definiuje prototyp obiektu, a więc już definiuje kontekst instancji. Nie kończ bindtego; używaj normalnego przekazywania zdarzeń zamiast duplikowania wszystkich wywołań funkcji w konstruktorze, ponieważ to powielanie zwiększa powierzchnię błędu i znacznie utrudnia śledzenie błędów, ponieważ problem może znajdować się w konstruktorze zamiast w miejscu, w którym wywołujesz kod. Oprócz nakładania ciężarów związanych z utrzymaniem na inne osoby, z którymi (z wyboru lub z wyboru) współpracujesz.
Tak, wiem, że doktorzy z reakcji mówią, że jest w porządku. Nie, nie rób tego.
Reaguj 16.8, używając komponentów funkcji z zaczepami
Od React 16.8 komponent funkcji (tj. Dosłownie tylko funkcja, która przyjmuje propsargument jako argument, może być używany tak, jakby był instancją klasy komponentu, bez pisania klasy), może również zostać podany stan, poprzez użycie hooków .
Jeśli nie potrzebujesz pełnego kodu klasy, a zadziała funkcja pojedynczej instancji, możesz teraz użyć useStatehaka, aby uzyskać sobie pojedynczą zmienną stanu, i jej funkcję aktualizacji, która działa mniej więcej tak samo jak powyższe przykłady, z wyjątkiem braku setStatewywołanie funkcji:
import { useState } from 'react';
function myFunctionalComponentFunction() {
const [input, setInput] = useState(''); // '' is the initial state value
return (
<div>
<label>Please specify:</label>
<input value={input} onInput={e => setInput(e.target.value)}/>
</div>
);
}
Wcześniej nieoficjalnym rozróżnieniem między klasami i komponentami funkcji było „komponenty funkcji nie mają stanu”, więc nie możemy się już dłużej za tym kryć: różnica między komponentami funkcji i komponentami klas można znaleźć na kilku stronach bardzo dobrze - pisemna reakcja na dokumentację (bez skrótu wyjaśnienia jednej linijki, aby wygodnie dla ciebie źle zinterpretować!), którą powinieneś przeczytać, abyś wiedział, co robisz, a tym samym wiedzieć, czy wybrałeś najlepsze (cokolwiek to dla ciebie znaczy) rozwiązanie do samodzielnego zaprogramowania z powodu twojego problemu.
this.onSubmit.bind(this);