- React.js: Wprowadzenie do kursu od podstaw
- Poznaj React.js
- Pierwszy komponent w React.js
- Props czyli atrybuty w React.js
- Podział na komponenty w React.js
- Klasy jako komponenty React.js
- Interakcja z komponentami React.js
- Stan komponentów React.js
- State w React.js 2
- Metody cyklu życia komponentu w React.js
- React.js w przykładach: filtrowanie statycznej listy
- Tworzenie aplikacji React.js dzięki create-react-app
- React.js na GitHub Pages dzięki create-react-app
- Testowanie aplikacji React.js — podstawy Enzyme
- Testowanie React.js w Enzyme — props, state i interakcje
- Poprawne bindowanie funkcji w React.js
- Odpowiadam na pytania: Babel, ECMAScript, destrukturyzacja, onClick, className
- Komunikacja pomiędzy komponentami w React.js
- Komunikacja z API w React.js
- Formularze w React.js — kontrolowane komponenty
- Formularze w React.js — niekontrolowane komponenty
- Odpowiadam na pytania: props, nawiasy klamrowe, funkcje vs klasy, import react
- TDD w React.js z pomocą react-testing-library
- Flux i Redux: globalny store i jednokierunkowy przepływ danych
- React + Redux — kurs: wprowadzenie i podstawy
- React + Redux — filtrowanie listy, proste selektory
- Projektowanie komponentów: Presentational & Container Components
- Asynchroniczność w Redux: redux-thunk
- Kiedy używać state, a kiedy Redux?
- Nowe metody cyklu życia: getDerivedStateFromProps i getSnapshotBeforeUpdate
- Leniwe ładowanie komponentów w React dzięki import
- Higher Order Reducers — Redux i powtarzanie kodu
- React Hooks — wprowadzenie i motywacja
- React Hooks: useState, czyli stan w komponentach funkcyjnych
- React Hooks: useState — wiele stanów, callbacki i inne niuanse
- React Hooks: useEffect — efekty uboczne w komponencie
- React Hooks a żądania do API
- useReducer — przenoszenie logiki poza komponent
- useMemo, useCallback, czyli rozwiązanie problemów ze zmieniającymi się propsami
- Wady React Hooks
- React Hooks: Piszemy własne hooki!
Dzisiaj zajmiesz się imlementacją formularzy w React.js. Już wcześniej dokonywałaś/eś interakcji z polami formularza — ale raczej w prosty sposób. Dzisiaj o formularzach kontrolowanych w React.js
Kontrolowane formularze w React.js
Kontrolowane komponenty w React.js (Controlled Components) — to takie komponenty, których wewnętrzny stan jest kontrolowany przez Reacta. O czym mówię? Weźmy prosty kod:
<input onChange={this.handleChange} />
Ten input
nie jest kontrolowany przez Reacta dlatego, że jego zawartość jest kontrolowana tylko przez użytkownika i przeglądarkę. React na nią nie wpływa. A tutaj ten sam input, ale już kontrolowany:
<input value={this.state.value} onChange={this.handleChange} />
Teraz jeśli spróbujesz coś wpisać w taki input — to aby zmiany były w ogóle widoczne, musisz też na bieżąco aktualizować wartość w state.value
. Jakby to miało wyglądać? Jest to dość proste:
class MyFirstForm extends React.Component {
state = {value: ''};
handleChange = (event) => {
this.setState({ value: event.target.value });
}
render() {
return (
<input value={this.state.value} onChange={this.handleChange} />
);
}
}
Tym sposobem React jest jedynym źródłem prawdy.
Elementy w formularzach
Przyjrzysz się teraz innym elementom, których używasz w formularzach 🙂 Wszystkie mogą być kontrolowane:
select
Tutaj warto zwrócić uwagę na dwie rzeczy:
- żaden option nie ma atrybutu
selected
znanego z HTML - element
<select>
ma atrybutvalue
Odpowiednia wartość value
sprawia, że React sam automatycznie wie, który element na liście jest wybrany i poprawnie renderuje formularz:
class MyFirstForm extends React.Component {
state = {value: 'blue'}
render() {
return (
<select value={this.state.value} onChange={this.handleChange}>
<option value="red">Czerwony</option>
<option value="blue">Niebieski</option>
<option value="green">Zielony</option>
</select>
);
}
}
W powyższym przykładzie wybrany będzie Niebieski.
textarea
W HTML-u element textarea
zachowuje się nieco inaczej niż pozostałe inputy. Jego wartość określona jest przez jego dziecko, a nie przez atrybut:
<textarea>Zawartość</textarea>
W React jest inaczej. Ustandaryzowano to i wykorzystywany jest atrybut value
:
<textarea value={this.state.value} />
Dzięki temu textarea
możesz traktować tak jak inne pola formularza bez konieczności robienia wyjątków 🙂
checkbox
i radio
Te inputy mają, podobnie jak w HTML, specjalny atrybut checked
do którego należy przekazać zmienną typu boolean
— true
lub false
.
<input type="checkbox" checked={this.state.isChecked} />
Demo
Przyszedł czas na demo — przykład kontrolowanego formularza w React.js:
See the Pen Kurs React.js — niekontrolowany formularz — typeofweb.com by Michał Miszczyszyn (@mmiszy) on CodePen.
Podsumowanie
Przedstawiłem tutaj podstawowy sposób obsługi formularzy w React.js. W kolejnym odcinku kursu porozmawiamy o formularzach niekontrolowanych. Poznaj React na szkoleniu z Type of Web!
Jeśli chcesz na bieżąco dowiadywać się o kolejnych częściach kursu React.js to koniecznie śledź mnie na Facebooku i zapisz się na newsletter.
Ćwiczenie
Ćwiczenie: Spróbuj tak zmienić obsługę formularza, aby niepotrzebne było używanie osobnej funkcji handle…Change
dla każdego elementu.
- React.js: Wprowadzenie do kursu od podstaw
- Poznaj React.js
- Pierwszy komponent w React.js
- Props czyli atrybuty w React.js
- Podział na komponenty w React.js
- Klasy jako komponenty React.js
- Interakcja z komponentami React.js
- Stan komponentów React.js
- State w React.js 2
- Metody cyklu życia komponentu w React.js
- React.js w przykładach: filtrowanie statycznej listy
- Tworzenie aplikacji React.js dzięki create-react-app
- React.js na GitHub Pages dzięki create-react-app
- Testowanie aplikacji React.js — podstawy Enzyme
- Testowanie React.js w Enzyme — props, state i interakcje
- Poprawne bindowanie funkcji w React.js
- Odpowiadam na pytania: Babel, ECMAScript, destrukturyzacja, onClick, className
- Komunikacja pomiędzy komponentami w React.js
- Komunikacja z API w React.js
- Formularze w React.js — kontrolowane komponenty
- Formularze w React.js — niekontrolowane komponenty
- Odpowiadam na pytania: props, nawiasy klamrowe, funkcje vs klasy, import react
- TDD w React.js z pomocą react-testing-library
- Flux i Redux: globalny store i jednokierunkowy przepływ danych
- React + Redux — kurs: wprowadzenie i podstawy
- React + Redux — filtrowanie listy, proste selektory
- Projektowanie komponentów: Presentational & Container Components
- Asynchroniczność w Redux: redux-thunk
- Kiedy używać state, a kiedy Redux?
- Nowe metody cyklu życia: getDerivedStateFromProps i getSnapshotBeforeUpdate
- Leniwe ładowanie komponentów w React dzięki import
- Higher Order Reducers — Redux i powtarzanie kodu
- React Hooks — wprowadzenie i motywacja
- React Hooks: useState, czyli stan w komponentach funkcyjnych
- React Hooks: useState — wiele stanów, callbacki i inne niuanse
- React Hooks: useEffect — efekty uboczne w komponencie
- React Hooks a żądania do API
- useReducer — przenoszenie logiki poza komponent
- useMemo, useCallback, czyli rozwiązanie problemów ze zmieniającymi się propsami
- Wady React Hooks
- React Hooks: Piszemy własne hooki!
Trochę to trwało, ale jest:
https://jsfiddle.net/OlaGruchala/jzLno7p0/10/
Bardzo dobre rozwiązanie 🙂 👍
Coś przegapiłem, albo nie doczytałem. W punkcie 8 kursu, napisałeś, że aby użyć state potrzebny jest konstruktor klasy a w nim wywalanie super(). W formularzu nie używasz konstruktora i działa. Dlaczego?
Rzeczywiście, jakoś umknęło mi, aby o tym jasno i wyraźnie wspomnieć! Dzięki za uwagę.
Otóż: Dzięki używaniu create-react-app, mam automatycznie włączone pewne presety w Babelu, które sprawiają, że mój kod jest prostszy. Konkretnie chodzi mi o opcję „Class Fields and Static Properties”, dzięki której te dwa zapisy są równoważne:
Heh nigdy nie umiałem się przekonać do żadnego frameworka, ani biblioteki, jedynie jakieś animacje w jquery, albo jakieś pojedyncze elementy jak charts.js czy scroll revealjs, ale ten React wydaje się świetny. BTW nie mam dziś czasu się zagłębiać, ale jak przeglądam to ten kurs to kawał dobrej roboty.
https://codepen.io/Rotarepmi/pen/gKGRwp?editors=1010
https://codepen.io/pawelziezio/pen/odNOPG?editors=1010
a co masz w wywolaniu ? 🙂 bo Twoje rozwiazanie wyglada kozacko
Zapewne miałem: .
https://codepen.io/MateuszFlisikowski/pen/PrGKMZ?editors=0010
http://ccoenraets.github.io/es6-tutorial/destructuring/
https://kursjs.pl/kurs/es6/destructuring.php
czy robię to ok, czy można lepiej?
Mam pytanie o textarea. Może ktoś znajdzie czas żeby zajrzeć 🙂 Próbuję wyczyścić textarea po kliknięciu w „send”, ale ponieważ jest to u mnie komponent kontrolowany to rozumiem że musiałabym to zrobić przez zmianę stanu. To z kolei nie daje efektu bo zmiana stanu w tym momencie czyści mi za szybko wartość i w efekcie zamiast tekstu wysyłam pusty string…
Jak to zrobić? Musze użyć niekontrolowanego komponentu?
https://codepen.io/OlaGruchala/pen/yrBBpw?editors=0010
Po kliknięciu w send, wyślij request, a następnie ustaw stan na pusty.
Mam i ja! Przesylanie argumentow w tym jezyku/frameworku jest na tyle roznych sposobow ze to jest jakas masakra.
https://pastebin.pl/view/2541f8f9
Nie potrzebujesz chyba metod handleMessageChange, handleColorChange, handleNameChange
Oczywiscie masz racje 😀 zapomanialem usunac tego co bylo na poczatku 🙂
https://pastebin.pl/view/5dfd7565
W sumie to jest chyba tylko jeden sposób — propsy? 🙂
Pewnie masz racje :p ale chodzi mi bardziej o takie rzeczy :
{this.props.contacts.map(this.contactToContactItem)}
onClick={this.displayMessage.bind(this,
message)
itd.
Wszystko cacy 😉 .. ale
często dane nie wyglądają tak prosto: state = {value: ”};
tylko
state = { data : [ { „value” : 1, … }, { „value2” : 2, … } ] jak później modyfikować takie dane?
Najlepiej bez mutowania, robiąc kopię:
this.setState(state => ({
data: state.data.map(el => {
…
})
}));
hmm w przykładzie z listą kontaktów
class App extends React.Component {
constructor() {
super();
this.state = { users : data,
test : 1 }
} …
i zew. danymi data = [ { „name” : „John” … } , „name” : „Lee” … ];
próbuję właśnie zdobić jak pokazałeś:
this.setState(prevState => {
return {
users : prevState.users.map( el => {
el.status = 'online'; // czy tu następuje mutacja?
return el;
})
};
}, function() { console.log( data ) });
Lista kontaktów nie odświeża się.
Musiałbyś mi podesłać cały kod 🙂
Tak, tam jest mutacja. Generalnie chcemy ich unikać, ale to nie powinno zablokować w tym przypadku renderowania i powinno działać.
hmm generalnie nie mogę znaleźć przyczyny:
const dataorg = JSON.parse(document.querySelector('#users_data').innerHTML ); const data = [...dataorg]; data[0].name = "Lennna"; console.log(dataorg); // obie [] są takie same, dlaczego???
Bo mutujesz obiekt, który jest w obu 🙂 data[0] i dataorg[0] to ta sama referencja.
tak mi się właśnie zdawało 😉
naprawiłem state taką konstrukcją:
tester = () => {
console.log( 'tester: ' + this.state.test );
this.setState(prevState => {
return {
users : function(){ let a = […prevState.users.map( (json, index) => {
let jsonnew = {…json};
if( index == 13 ){ jsonnew.status = „online”; }
return jsonnew;
})];
// powoduje update
a.push({ „id” : a.length + 1, „login” : „k9”, „name” : „Suzanne”, „surname” : „Lee”, „department” : „Test” + ( a.length + 1 ) });
console.log(a);
return a;
}(),
test : prevState.test + 1
};
}, function() { console.log( data ); console.log( this.state.users ); console.log( this.state.test ) });
}
@edit:
znalazłem również ciekawe rozwiązanie:
… users : function(){
// test 2
let stateCopy = JSON.parse( JSON.stringify( prevState.users ) );
stateCopy[13].status = 'online';
return stateCopy;
}(), …