Gdy jest to ważne, aby przejść propsdo super()i dlaczego?
class MyComponent extends React.Component {
constructor(props) {
super(); // or super(props) ?
}
}
Gdy jest to ważne, aby przejść propsdo super()i dlaczego?
class MyComponent extends React.Component {
constructor(props) {
super(); // or super(props) ?
}
}
Odpowiedzi:
Jest tylko jeden powód, dla którego należy przejść propsdo super():
Gdy chcesz uzyskać dostęp this.propsdo konstruktora.
Przechodzący:
class MyComponent extends React.Component {
constructor(props) {
super(props)
console.log(this.props)
// -> { icon: 'home', … }
}
}
Nie przechodzi:
class MyComponent extends React.Component {
constructor(props) {
super()
console.log(this.props)
// -> undefined
// Props parameter is still available
console.log(props)
// -> { icon: 'home', … }
}
render() {
// No difference outside constructor
console.log(this.props)
// -> { icon: 'home', … }
}
}
Zauważ, że przechodząc lub nie przechodząc propsdo superma żadnego wpływu na późniejsze zastosowań this.propszewnątrz constructor. Oznacza to render, że shouldComponentUpdateprocedury obsługi zdarzeń zawsze mają do niego dostęp.
Jest to wyraźnie powiedziane w jednej Sophie Alpert w odpowiedzi na podobne pytanie.
Dokumentacja - Stan i cykl życia, Dodawanie stanu lokalnego do klasy, punkt 2 - zaleca:
Komponenty klasy powinny zawsze wywoływać konstruktor podstawowy za pomocą
props.
Jednak nie podano żadnego powodu. Możemy spekulować, że dzieje się tak z powodu podklasy lub ze względu na kompatybilność w przyszłości.
(Dzięki @MattBrowne za link)
this.propsjest undefinedchyba że przekazany do super(). Tak czy inaczej, nie wpływa później renderingu lub dostępności this.propsw render()funkcji.
super, masz do nich odniesienie w konstruktorze.
propsdo super(): facebook.github.io/react/docs/… . Nie jestem pewien, dlaczego, skoro, jak wskazałeś, this.propsjest dostępny w inny sposób w jakikolwiek sposób ... być może polecają to dla przyszłej kompatybilności na wypadek, gdyby przyszłe wersje React mogły chcieć coś zrobić propsw konstruktorze?
propsdo superkiedy, jak wspomniałem, propsparametr jest tam dostępne dla nas do wykorzystania wewnątrz konstruktora i this.propsdziała wszędzie? Czy w ogóle jest korzyść z używania this.propstylko po prostu props? Czy złą praktyką jest rozkładanie propsw konstruktorze? Chyba nadal nie widać przypadek, że kiedykolwiek trzeba przejść propsdo super, ale jestem gotów się założyć, że to tylko moja ignorancja, ha.
super(props), możesz wywoływać metody this.props z konstruktora , na przykład this.doStuffUsingThisDotProps(), bez konieczności przekazywania parametru props do tych metod / funkcji. Właśnie napisałem konstruktor, który to robi, co, jak się wydaje, wymaga super(props)najpierw użycia , zgodnie z odpowiedziami na to pytanie.
W tym przykładzie rozszerzasz React.Componentklasę i zgodnie ze specyfikacją ES2015 konstruktor klasy potomnej nie może korzystać z niego, thisdopóki super()nie zostanie wywołany; także konstruktory klasy ES2015 muszą wywoływać, super()jeśli są podklasami.
class MyComponent extends React.Component {
constructor() {
console.log(this); // Reference Error
}
render() {
return <div>Hello {this.props.name}</div>;
}
}
Dla kontrastu:
class MyComponent extends React.Component {
constructor() {
super();
console.log(this); // this logged to console
}
render() {
return <div>Hello {this.props.name}</div>;
}
}
Więcej szczegółów zgodnie z tą doskonałą odpowiedzią na przepełnienie stosu
Możesz zobaczyć przykłady komponentów utworzonych przez rozszerzenie React.Componentklasy, które nie wywołują, super()ale zauważysz, że nie mają one constructor, dlatego nie jest to konieczne.
class MyOtherComponent extends React.Component {
render() {
return <div>Hi {this.props.name}</div>;
}
}
Pewnym punktem zamieszania, który widziałem u niektórych programistów, z którymi rozmawiałem, jest to, że składniki, które nie mają, constructora zatem nie wywołują super()nigdzie, nadal są this.propsdostępne w render()metodzie. Pamiętaj, że ta reguła i ta potrzeba utworzenia thispowiązania constructordotyczy tylko constructor.
super()i super(props)).
Po przejściu propsdo superrekwizyty zostaną przypisane do this. Spójrz na następujący scenariusz:
constructor(props) {
super();
console.log(this.props) //undefined
}
Jakkolwiek, kiedy to robisz:
constructor(props) {
super(props);
console.log(this.props) //props will get logged.
}
Zgodnie z kodem źródłowym
function ReactComponent(props, context) {
this.props = props;
this.context = context;
}
musisz zdać za propskażdym razem, gdy masz rekwizyty i nie wkładasz ich this.propsręcznie.
this.props = propsi super(props)to to samo?
this.propsna „z zewnątrz” - niezależnie od tego, co dzieje się w konstruktorze.
Dan Abramov napisał artykuł na ten temat:
Dlaczego piszemy super (rekwizyty)?
Istotą tego jest to, że warto mieć w zwyczaju przekazywanie go, aby uniknąć tego scenariusza, i szczerze mówiąc, nie widzę, aby miało to miejsce:
// Inside React
class Component {
constructor(props) {
this.props = props;
// ...
}
}
// Inside your code
class Button extends React.Component {
constructor(props) {
super(); // 😬 We forgot to pass props
console.log(props); // ✅ {}
console.log(this.props); // 😬 undefined
}
// ...
}
super() służy do wywołania konstruktora nadrzędnego.
super(props)przejdzie propsdo konstruktora nadrzędnego.
Z twojego przykładu super(props)wywołałby React.Componentkonstruktor propsjako argument.
Więcej informacji na super:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super
Podczas implementacji constructor()funkcji w komponencie React super()jest wymagane. Pamiętaj, że twój MyComponentelement rozszerza lub pożycza funkcjonalność z React.Componentklasy podstawowej.
Ta klasa bazowa ma własną constructor()funkcję, która zawiera w sobie trochę kodu, aby skonfigurować dla nas nasz komponent React.
Kiedy zdefiniujemy constructor() funkcję w naszej MyComponentklasie, w zasadzie zastępujemy lub zastępujemy constructor()funkcję wewnątrz React.Componentklasy, ale nadal musimy upewnić się, że cały kod instalacyjny w tej constructor()funkcji jest nadal wywoływany.
Tak aby zapewnić, że React.Component„sconstructor() funkcja jest wywoływana, nazywamy super(props). super(props)jest odniesieniem do constructor()funkcji rodziców , to wszystko.
Musimy dodawać za super(props)każdym razem, gdy definiujemy constructor()funkcję wewnątrz komponentu opartego na klasie.
Jeśli tego nie zrobimy, pojawi się błąd informujący, że musimy zadzwonić super(props).
Cały powód tego zdefiniowania constructor() jest zainicjowanie naszego obiektu stanu.
Aby więc zainicjować nasz obiekt stanu, pod super wywołaniem zamierzam napisać:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
// React says we have to define render()
render() {
return <div>Hello world</div>;
}
};
Zdefiniowaliśmy więc naszą constructor()metodę, zainicjowaliśmy nasz obiekt stanu, tworząc obiekt JavaScript, przypisując mu właściwość lub parę klucz / wartość, przypisując wynik tej operacji this.state. Teraz oczywiście jest to tylko przykład, więc tak naprawdę nie przypisałem pary klucz / wartość do obiektu stanu, jest to po prostu pusty obiekt.
Oto skrzypce, które zrobiłem: jsfiddle.net . Pokazuje, że rekwizyty domyślnie nie są przypisane do konstruktora. Jak rozumiem, są one oparte na metodzie React.createElement. Stąd super(props)powinna być wywoływana tylko kiedy assings ręcznie konstruktor nadklasy w propscelu this.props. Jeśli tylko przedłużysz React.Componentpołączenie super(props), nic nie zrobisz z rekwizytami. Może zostanie zmieniony w następnych wersjach React.
Tutaj nie otrzymamy tego w konstruktorze, więc zwróci niezdefiniowane, ale będziemy mogli pobrać to poza funkcją konstruktora
class MyComponent extends React.Component {
constructor() {
console.log(this); // Reference Error i.e return undefined
}
render() {
return <div>Hello {this.props.name}</div>;
}
}
Jeśli używamy super (), możemy pobrać również zmienną „this” wewnątrz konstruktora
class MyComponent extends React.Component {
constructor() {
super();
console.log(this); // this logged to console
}
render() {
return <div>Hello {this.props.name}</div>;
}
}
Więc kiedy używamy super (); będziemy mogli to pobrać, ale this.props będzie niezdefiniowany w konstruktorze. Ale oprócz konstruktora this.props nie zwróci niezdefiniowanego.
Jeśli użyjemy super (rekwizyty), możemy również użyć wartości this.props wewnątrz konstruktora
Jeśli chcesz użyć this.props w konstruktorze, musisz przekazać rekwizyty super. W przeciwnym razie nie ma to znaczenia, ponieważ React ustawia .props na instancję z zewnątrz natychmiast po wywołaniu konstruktora.
Aby zareagować na wersję 16.6.3, używamy super (rekwizyty) do zainicjowania nazwy elementu stanu : this.props.name
constructor(props){
super(props);
}
state = {
name:this.props.name
//otherwise not defined
};