Mam prosty element reagujący z formularzem, który moim zdaniem ma jedno kontrolowane wejście:
import React from 'react';
export default class MyForm extends React.Component {
constructor(props) {
super(props);
this.state = {}
}
render() {
return (
<form className="add-support-staff-form">
<input name="name" type="text" value={this.state.name} onChange={this.onFieldChange('name').bind(this)}/>
</form>
)
}
onFieldChange(fieldName) {
return function (event) {
this.setState({[fieldName]: event.target.value});
}
}
}
export default MyForm;
Po uruchomieniu aplikacji pojawia się następujące ostrzeżenie:
Ostrzeżenie: MyForm zmienia niekontrolowane wprowadzanie tekstu kontrolowanego. Elementy wejściowe nie powinny przełączać się z niekontrolowanego na kontrolowane (lub odwrotnie). Wybierz między użyciem kontrolowanego lub niekontrolowanego elementu wejściowego przez cały okres użytkowania komponentu
Uważam, że mój wkład jest kontrolowany, ponieważ ma wartość. Zastanawiam się, co robię źle?
Używam React 15.1.0
źródło
name={'question_groups.${questionItem.id}'}
?value
rekwizyt ma wartość inną niż zero / niezdefiniowana. Podpora nie musi odpowiadać zmiennej stanu (może to być po prostu stała, a komponent nadal będzie uważany za sterowany). Odpowiedź Adama jest bardziej poprawna i powinna zostać zaakceptowana.Kiedy renderujesz swój komponent po raz pierwszy,
this.state.name
nie jest on ustawiony, więc ocenia on naundefined
lubnull
, i kończysz przekazywanievalue={undefined}
lubvalue={null}
na twójinput
.Kiedy ReactDOM sprawdza, czy pole jest kontrolowane, sprawdza, czy
value != null
(pamiętaj, że to!=
nie jest!==
), a ponieważundefined == null
w JavaScript decyduje, że jest niekontrolowane.Kiedy
onFieldChange()
jest wywoływany,this.state.name
jest ustawiany na wartość ciągu, dane wejściowe przechodzą od niekontrolowanego do kontrolowanego.Jeśli zrobisz to
this.state = {name: ''}
w swoim konstruktorze, ponieważ'' != null
twoje dane wejściowe będą miały wartość przez cały czas, a ten komunikat zniknie.źródło
this.props.<whatever>
, co było moim problemem. Dzięki, Adam!render()
, lub wyrażenie w samym znaczniku - cokolwiek, co zostanie ocenioneundefined
. Cieszę się, że mogłem pomóc!name
”.undefined
że początkowo przekazywana jest wartość . Raczej fakt, żethis.state.name
nie istnieje jako zmienna stanu, powoduje, że dane wejściowe są niekontrolowane. Na przykład posiadaniethis.state = { name: undefined };
spowoduje, że wejście będzie kontrolowane. Należy rozumieć, że ważne jest, skąd pochodzi wartość, a nie jaka jest wartość.this.state = { name: undefined }
nadal spowoduje niekontrolowane wprowadzanie danych.<input value={this.state.name} />
desugars toReact.createElement('input', {value: this.state.name})
. Ponieważ uzyskuje się dostęp do nieistniejącej właściwości obiektu, zwracaundefined
to dokładnie to samo wywołanie funkcji -React.createElement('input', {value: undefined})
czyname
nie jest ustawione ani jawnie ustawione naundefined
, więc React zachowuje się w ten sam sposób. Możesz zobaczyć to zachowanie w tym JSFiddle.Innym podejściem może być ustawienie wartości domyślnej w danych wejściowych, na przykład:
źródło
Wiem, że inni już na to odpowiedzieli. Ale bardzo ważny czynnik, który może pomóc innym osobom, które mają podobny problem:
Musisz mieć
onChange
moduł obsługi dodany w polu wejściowym (np. Pole tekstowe, pole wyboru, radio itp.). Zawsze obsługuj aktywność przezonChange
moduł obsługi.Przykład:
Podczas pracy z polem wyboru może być konieczne obsługiwanie jego
checked
stanu za pomocą!!
.Przykład:
źródło
Prostym rozwiązaniem tego problemu jest ustawienie domyślnie pustej wartości:
źródło
Jednym potencjalnym minusem przy ustawianiu wartości pola na „” (pusty ciąg) w konstruktorze jest to, że pole jest polem opcjonalnym i nie jest edytowane. O ile nie wykonasz masowania przed opublikowaniem formularza, pole zostanie utrwalone do przechowywania danych jako pusty ciąg zamiast NULL.
Ta alternatywa pozwoli uniknąć pustych ciągów:
źródło
Kiedy używasz
onChange={this.onFieldChange('name').bind(this)}
w swoich danych wejściowych, musisz zadeklarować swój pusty ciąg znaków jako wartość pola właściwości.niewłaściwy sposób:
właściwa droga:
źródło
W moim przypadku brakowało mi czegoś naprawdę trywialnego.
<input value={state.myObject.inputValue} />
Mój stan był następujący, gdy otrzymywałem ostrzeżenie:
Poprzez naprzemienne zmienianie mojego stanu w celu odniesienia danych wejściowych mojej wartości , mój problem został rozwiązany:
źródło
Jeśli rekwizyty w komponencie zostały przekazane jako stan, ustaw wartość domyślną dla tagów wejściowych
źródło
Ustaw wartość właściwości „name” w stanie początkowym.
źródło
Aktualizacja do tego. Do użycia haków React
const [name, setName] = useState(" ")
źródło
" "
nie""
? Powoduje to utratę tekstu podpowiedzi, a po kliknięciu i wpisaniu pojawia się sprytna spacja przed wprowadzeniem danych.Zasadniczo dzieje się tak tylko wtedy, gdy nie kontrolujesz wartości pola przy uruchomieniu aplikacji i po uruchomieniu jakiegoś zdarzenia lub funkcji lub zmianie stanu, próbujesz teraz kontrolować wartość w polu wejściowym.
To przejście z braku kontroli nad danymi wejściowymi, a następnie nad nimi kontroli, powoduje, że problem występuje przede wszystkim.
Najlepszym sposobem na uniknięcie tego jest zadeklarowanie wartości dla danych wejściowych w konstruktorze komponentu. Tak, aby element wejściowy miał wartość od początku aplikacji.
źródło
Aby dynamicznie ustawiać właściwości stanu dla danych wejściowych formularza i kontrolować je, możesz zrobić coś takiego:
źródło
Po prostu utwórz rezerwę na „”, jeśli this.state.name ma wartość NULL.
Działa to również ze zmiennymi useState.
źródło