DaftAcademy / frontend_levelup_2018

11 stars 33 forks source link

komponent kontrolowany wyrzuca ostrzeżenie #5

Open ghost opened 6 years ago

ghost commented 6 years ago

To jest fragment z dokumentacji Reacta

With a controlled component, every state mutation will have an associated handler function. This makes it straightforward to modify or validate user input. For example, if we wanted to enforce that names are written with all uppercase letters, we could write handleChange as:

handleChange(event) {
  this.setState({value: event.target.value.toUpperCase()});
}

Otóż próbowałem u siebie w pracy domowej zastosować podobne rozwiązanie, jednak dostałem ostrzeżenie:

Warning: A component is changing an uncontrolled input of type text to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info: https://fb.me/react-controlled-components

Przeczytałem ze dwa razy tę stronę i nie bardzo rozumiem dlaczego te ostrzeżenie się pojawia. Co więcej, próbowałem zastosować dokładanie taki kod jak powyżej - i ostrzeżenie jest nadal na tym oryginalnym kodzie ze strony. Jeżeli nie modyfikuję event.target.value to wszystko gra. Sprawdziłem też wpływ wartości początkowej, bo takie były sugestie na Stack Overflow ale u mnie nie pomaga. Dalej: mimo ostrzeżenia dalszy rezultat jest zgodny z oczekiwaniami. Ktoś coś?

przywartya commented 6 years ago

Nie do końca rozumiem w którym momencie ten warning się pojawia :-1: Ani u siebie, ani na codepen (https://codepen.io/anon/pen/OZJqYO?editors=0010) go nie widzę. Może podrzucisz codepena z twoim warningiem i wtedy pomyślimy? :)

mbychawski commented 6 years ago

@PiotrMaksymiuk podlinkuj swój kod to rzucę okiem :)

ghost commented 6 years ago

Proszę bardzo, oto on

Praca domowa

|

Praca domowa

... |

|

|

Ogólnie idea jest taka, żeby

ten sam element obrabiał zarówno okno wejściowe wartości początkowej jak i końcowej zakładał maskę na wprowadzane wartości (tylko cyfry) aktualizował stan dopiero kiedy nacisnę Submit

Sprawdziłem swoją maskę - w twoim penie oczywiście gra.

I o ile wszystko gra przy jednym input to już nie przy dwóch zaczynają się schody.

Formalnie to co napisałem zachowuje się tak jakbym oczekiwał (prawie) Maska działa, pozostaje jeszcze dodać dwie zmienne pośrednie aby przypisać wartości wprowadzone do tego co będzie widoczne na zewnątrz dopiero po submit (na razie submit jest niedokończony);w każdym razie do this.state. ... przypisywane są pożądane wartości.

Dochodzę do wniosku, że nie do końca ogarniam działanie elementu input w Reakcie. Krótko mówiąc, w przykładach wszędzie używane jest słowo value i chyba jest używane zarówno jako nazwa zmiennej jak i elementu pola input. I chyba gdzieś tutaj się gubię :(

Jakbyś mógł mi to rozjaśnić byłoby wspaniale :)

On Wednesday, April 18, 2018, 11:27:18 PM GMT+2, Adam <notifications@github.com> wrote:  

Nie do końca rozumiem w którym momencie ten warning się pojawia 👎 Ani u siebie, ani na codepen (https://codepen.io/anon/pen/OZJqYO?editors=0010) go nie widzę. Może podrzucisz codepena z twoim warningiem i wtedy pomyślimy? :)

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or mute the thread.

majkamajka commented 6 years ago

@PiotrMaksymiuk wrzuć kod jeszcze raz, i odpisuj raczej z poziomu githuba, niż z maila.

ghost commented 6 years ago

OK za chwilę - dostałem odpowiedź na maila to wpisałem w mailu Już się robi

On Thursday, April 19, 2018, 11:00:47 AM GMT+2, majkamajka <notifications@github.com> wrote:  

@PiotrMaksymiuk wrzuć kod jeszcze raz, i odpisuj raczej z poziomu githuba, niż z maila.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

ghost commented 6 years ago

https://codepen.io/Kiszuriwalilibori/pen/jxEWej/?editors=1111

Gotowe

mbychawski commented 6 years ago

Ok, problem jest prosty do rozwiązania.

Tutaj robisz coś bardzo dziwnego:

this.state = {value: ''};
this.state ={start:''};
this.state ={meta:''};
this.state ={newStart:''};

ostatecznie po wywołaniu tego kodu this.state jest równy {newStart: ""}

Zatem przy pierwszym renderze input: <input type="text" value={this.state.start} onChange={this.handleChangeStart} /> dostaje value = {undefined} zatem jest uncontrolled. Dopiero przy pierwszej zmianie, w state pojawia się odpowiednia wartość i input staje się controlled.

Rozwiązaniem jest zaqinicjowanie komplentego state w konstruktorze.

this.state = {
  value: '',
  start:'',
  meta:'',
  newStart:'',
};
mkaczkowski commented 6 years ago

idac dalej moze lepiej zamiast string'a '' to ustawic 0 lub -1 ?

ghost commented 6 years ago

Dzięki za pomoc, wrzucenie tego w obiekt było właśnie tym co przeoczyłem, z rozpędu inicjalizowałem state raz za razem. A drugie niezupełnie rozumiem

ghost commented 6 years ago

A, że przy twardym typowaniu wyrzuciłoby type mismatch, dzięki