Zaczynam od React.js i chcę zrobić prosty formularz, ale w dokumentacji znalazłem na to dwa sposoby.
Pierwszy używa Refs :
var CommentForm = React.createClass({
handleSubmit: function(e) {
e.preventDefault();
var author = React.findDOMNode(this.refs.author).value.trim();
var text = React.findDOMNode(this.refs.text).value.trim();
if (!text || !author) {
return;
}
// TODO: send request to the server
React.findDOMNode(this.refs.author).value = '';
React.findDOMNode(this.refs.text).value = '';
return;
},
render: function() {
return (
<form className="commentForm" onSubmit={this.handleSubmit}>
<input type="text" placeholder="Your name" ref="author" />
<input type="text" placeholder="Say something..." ref="text" />
<input type="submit" value="Post" />
</form>
);
}
});
A druga korzysta stan wewnątrz React komponent:
var TodoTextInput = React.createClass({
getInitialState: function() {
return {
value: this.props.value || ''
};
},
render: function() /*object*/ {
return (
<input className={this.props.className}
id={this.props.id}
placeholder={this.props.placeholder}
onBlur={this._save}
value={this.state.value}
/>
);
},
_save: function() {
this.props.onSave(this.state.value);
this.setState({value: ''
});
});
Nie widzę zalet i wad tych dwóch alternatyw, jeśli takie istnieją. Dzięki.
Odpowiedzi:
Krótka wersja: unikaj odniesień.
Są złe z punktu widzenia łatwości konserwacji i tracą wiele z prostoty, jaką zapewnia renderowanie modelu WYSIWYG.
Masz formularz. Musisz dodać przycisk, który resetuje formularz.
Masz pole numer CCV w danych wejściowych i kilka innych pól w aplikacji, które są liczbami. Teraz musisz wymusić, aby użytkownik wprowadzał tylko liczby.
Ech, nieważne, premier chce, żebyśmy zrobili cienie w czerwonym pudełku, jeśli jest nieważne.
Musimy oddać kontrolę rodzicowi. Dane są teraz w rekwizytach i musimy reagować na zmiany.
sed -e 's/this.state/this.props/' 's/handleChange/onChange/' -i form.js
Ludzie myślą, że refs są „łatwiejsze” niż utrzymywanie ich w stanie. Może to być prawdą przez pierwsze 20 minut, ale z mojego późniejszego doświadczenia to nieprawda. Postaw się w sytuacji, gdy powiesz „Tak, zrobię to za 5 minut” zamiast „Jasne, po prostu przepiszę kilka składników”.
źródło
React.findDOMNode(this.refs.foo)
. Jeśli np. Zmienisz,this.refs.foo.props.bar
nic się nie stanie.<input onChange={this.handleChange} value={this.state.foo} />
zmienisz go na<input onChange={this.props.handleChange} value={this.props.foo} />
lub zmodyfikujesz funkcje handleChange, aby wywoływały wywołania zwrotne w właściwościach. Tak czy inaczej, jest to kilka małych oczywistych zmian.input
Idealne jest komponowanie każdego pola, w którym każde utrzymuje swój własny stan. W pewnym momencie musimy pogodzić te różne niezależne państwa z jakimś większym modelem. Może mamy autozapis na liczniku czasu lub po prostu oszczędzamy.componentWillUnmount
Tutaj uważam, że jestrefs
idealny, podczas uzgadnianiastate
z każdego wyciągamy wartośćref
i żadna nie jest mądrzejsza. Zgadzam się w większości przypadkówstate
jest odpowiedzią, ale przy dużej liczbieinputs
użycie odpowiedniegorefs
wzorca jest dobrodziejstwem dla wydajnościWidziałem, jak kilka osób cytuje powyższą odpowiedź jako powód, by „nigdy nie używać referencji” i chcę wyrazić swoją opinię (a także kilku innych programistów React, z którymi rozmawiałem).
Sentyment „nie używaj referencji” jest poprawny, gdy mówimy o używaniu ich w instancjach komponentów. Oznacza to, że nie powinieneś używać referencji jako sposobu na przechwytywanie instancji komponentów i wywoływanie na nich metod. Jest to niewłaściwy sposób używania referencji i ma to miejsce, gdy sędziowie szybko idą na południe.
Prawidłowym (i bardzo użytecznym) sposobem użycia referencji jest użycie ich do uzyskania jakiejś wartości z DOM. Na przykład, jeśli masz pole wejściowe dołączające ref do tego wejścia, to późniejsze pobranie wartości przez ref jest w porządku. Bez tego musisz przejść przez dość zorganizowany proces, aby zapewnić aktualizację pola wejściowego do stanu lokalnego lub magazynu flux - co wydaje się niepotrzebne.
Edycja 2019: Witajcie przyjaciele przyszłości. Oprócz tego, o czym wspomniałem kilka lat temu ^, dzięki React Hooks, referencje są również świetnym sposobem na śledzenie danych między renderami i nie ograniczają się do przechwytywania węzłów DOM.
źródło
refs
i uzyskaj wartość stanu. Wydaje się, że to naprawdę ładny wzór.TL; DR Ogólnie rzecz biorąc,
refs
sprzeciwiaj się deklaratywnej filozofii Reacta , więc powinieneś używać ich w ostateczności. Używaj wstate / props
miarę możliwości.Aby zrozumieć, gdzie używasz
refs
vsstate / props
, spójrzmy na niektóre zasady projektowania, których przestrzega React.Dokumentacja Per React dotycząca
refs
Zgodnie z zasadami projektowania firmy React dotyczącymi kreskowania ucieczki
Co oznacza, że zespół Reacta sugeruje unikanie
refs
i używaniestate / props
wszystkiego, co można zrobić w sposób reaktywny / deklaratywny.@Tyler McGinnis udzielił bardzo dobrej odpowiedzi , stwierdzając również, że
Chociaż możesz to zrobić, będziesz działać przeciwko filozofii React. Jeśli masz wartość w danych wejściowych, z pewnością pochodzi ona z
state / props
. Aby kod był spójny i przewidywalny, również powinieneś się tego trzymaćstate / props
. Przyjmuję do wiadomości, żerefs
czasami daje to szybsze rozwiązanie, więc jeśli wykonasz dowód słuszności koncepcji, szybkie i brudne jest dopuszczalne.To pozostawia nas z kilku przypadków użycia betonu dla
refs
źródło
Ten post jest stary.
Podzielę się moim małym doświadczeniem w jednej sprawie w tej sprawie.
Pracowałem nad dużym komponentem (414 linii) z dużą ilością „dynamicznych” danych wejściowych i dużą ilością danych w pamięci podręcznej. (Nie pracuję sam na stronie, a zmysły podpowiadają mi, że strukturę kodu pewnie dałoby się lepiej rozłożyć, ale nie o to chodzi (no cóż, mogłoby być, ale sobie z tym radzę)
Najpierw pracowałem ze stanem, aby obsłużyć wartości danych wejściowych:
i oczywiście w wejściach:
Renderowanie było tak ciężkie, że zmiana danych wejściowych była przerywana na **** (nie próbuj trzymać klawisza wciśniętego, tekst pojawiłby się dopiero po przerwie)
Byłem pewien, że mogę tego uniknąć, używając ref.
skończyło się tak:
i na wejściach:
[w moim przypadku dane wejściowe to Material-UI TextField, więc było:
]
Dzięki temu nie ma ponownego renderowania, wejście jest płynne, funkcjonalność działa tak samo. Oszczędza cykle i obliczenia, a więc także energię. Zrób to dla Ziemi x)
Mój wniosek: może być nawet potrzebny useRef dla wartości wejściowych.
źródło