Jak ustawić domyślne właściwości komponentu w komponencie React

140

Używam poniższego kodu, aby ustawić domyślne właściwości komponentu React, ale to nie działa. W render()metodzie widzę, że wynik „undefined props” został wydrukowany na konsoli przeglądarki. Jak mogę zdefiniować domyślną wartość dla właściwości komponentów?

export default class AddAddressComponent extends Component {

render() {
   let {provinceList,cityList} = this.props
    if(cityList === undefined || provinceList === undefined){
      console.log('undefined props')
    }
    ...
}

AddAddressComponent.contextTypes = {
  router: React.PropTypes.object.isRequired
}

AddAddressComponent.defaultProps = {
  cityList: [],
  provinceList: [],
}

AddAddressComponent.propTypes = {
  userInfo: React.PropTypes.object,
  cityList: PropTypes.array.isRequired,
  provinceList: PropTypes.array.isRequired,
}
Joey Yi Zhao
źródło

Odpowiedzi:

142

Zapomniałeś zamknąć Classwspornik.

class AddAddressComponent extends React.Component {
  render() {
    let {provinceList,cityList} = this.props
    if(cityList === undefined || provinceList === undefined){
      console.log('undefined props')
    } else {
      console.log('defined props')
    }

    return (
      <div>rendered</div>
    )
  }
}

AddAddressComponent.contextTypes = {
  router: React.PropTypes.object.isRequired
};

AddAddressComponent.defaultProps = {
  cityList: [],
  provinceList: [],
};

AddAddressComponent.propTypes = {
  userInfo: React.PropTypes.object,
  cityList: React.PropTypes.array.isRequired,
  provinceList: React.PropTypes.array.isRequired,
}

ReactDOM.render(
  <AddAddressComponent />,
  document.getElementById('app')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app" />

Serhii Baraniuk
źródło
93

Dla tych, którzy używają czegoś takiego jak babel stage-2 lub transform-class-properties :

import React, { PropTypes, Component } from 'react';

export default class ExampleComponent extends Component {
   static contextTypes = {
      // some context types
   };

   static propTypes = {
      prop1: PropTypes.object
   };

   static defaultProps = {
      prop1: { foobar: 'foobar' }
   };

   ...

}

Aktualizacja

W React v15.5 PropTypeszostał przeniesiony z głównego pakietu React ( link ):

import PropTypes from 'prop-types';

Edytować

Jak zauważył @johndodo, staticwłaściwości klas w rzeczywistości nie są częścią specyfikacji ES7, ale są obecnie obsługiwane tylko przez babel. Zaktualizowano, aby to odzwierciedlić.

treyhakanson
źródło
dziękuję za odpowiedź, ale chciałem dowiedzieć się więcej na ten temat, więc zajrzałem do react/ nativedoc i nie mogłem ich znaleźć, gdzie jest na to dokument?
farmcommand2
Nie sądzę, by było to wyraźnie w dokumentach Reacta, ale jeśli rozumiesz, jakie staticsą zmienne klasowe, ma to sens, więc sugeruję przeczytanie o nich na MDN . Zasadniczo składnia w dokumentacji jest równoważna z tym, ponieważ oba dodają informacje o właściwościach do samej klasy, a nie do poszczególnych instancji.
treyhakanson
1
import zostanie zmieniony na: import PropTypes z 'prop-types';
tibi
1
@treyhakanson Link do MDN mówi tylko o metodach statycznych, a nie o zmiennych. Nie mogłem znaleźć odniesienia do statycznych zmiennych klas, z wyjątkiem Babel . Czy jest to zaakceptowana właściwość ES7?
johndodo
15

Najpierw musisz oddzielić swoją klasę od dalszych rozszerzeń, np. Nie możesz rozszerzyć AddAddressComponent.defaultPropsw ramach, classzamiast tego przenieść ją na zewnątrz.

Polecam również przeczytanie o cyklu życia Konstruktora i Reacta: zobacz Specyfikacje komponentów i cykl życia

Oto, czego chcesz:

import PropTypes from 'prop-types';

class AddAddressComponent extends React.Component {
  render() {
    let { provinceList, cityList } = this.props;
    if(cityList === undefined || provinceList === undefined){
      console.log('undefined props');
    }
  }
}

AddAddressComponent.contextTypes = {
  router: PropTypes.object.isRequired
};

AddAddressComponent.defaultProps = {
  cityList: [],
  provinceList: [],
};

AddAddressComponent.propTypes = {
  userInfo: PropTypes.object,
  cityList: PropTypes.array.isRequired,
  provinceList: PropTypes.array.isRequired,
}

export default AddAddressComponent;
Ilanus
źródło
Czy na pewno potrzebują constructori componentWillReceiveProps? Wydaje mi się, że OP właśnie zapomniał o zamykającym nawiasie dla swojej deklaracji klasy.
ivarni
@ivarni niekoniecznie, ale ważne jest, aby rozumiał cykl życia, konstruktora i rozszerzenia klas. więc będzie wiedział, co robi. więc dodałem kilka linków zewnętrznych
Ilanus
2
W porządku, po prostu myślę, że powiedzenie „musisz” nie jest do końca poprawne. Wolałbym raczej powiedzieć coś w rodzaju „możesz dodać te metody, aby obserwować cykl życia” . W przeciwnym razie dobra odpowiedź :)
ivarni
9

Możesz także użyć zadania Destrukturyzacja.

class AddAddressComponent extends React.Component {
  render() {

    const {
      province="insertDefaultValueHere1",
      city="insertDefaultValueHere2"
    } = this.props

    return (
      <div>{province}</div>
      <div>{city}</div>
    )
  }
}

Podoba mi się to podejście, ponieważ nie musisz pisać dużo kodu.

Sam Henderson
źródło
2
Problem, który tu widzę, polega na tym, że możesz chcieć użyć domyślnych właściwości w wielu metodach.
Gerard Brull
5

użyj statycznych defaultProps, takich jak:

export default class AddAddressComponent extends Component {
    static defaultProps = {
        provinceList: [],
        cityList: []
    }

render() {
   let {provinceList,cityList} = this.props
    if(cityList === undefined || provinceList === undefined){
      console.log('undefined props')
    }
    ...
}

AddAddressComponent.contextTypes = {
  router: React.PropTypes.object.isRequired
}

AddAddressComponent.defaultProps = {
  cityList: [],
  provinceList: [],
}

AddAddressComponent.propTypes = {
  userInfo: React.PropTypes.object,
  cityList: PropTypes.array.isRequired,
  provinceList: PropTypes.array.isRequired,
}

Zaczerpnięte z: https://github.com/facebook/react-native/issues/1772

Jeśli chcesz sprawdzić typy, zobacz, jak używać PropTypes w odpowiedziach treyhakansona lub Ilana Hasanova lub przejrzyj wiele odpowiedzi w powyższym linku.

Brandon Keith Biggs
źródło
4

Możesz ustawić domyślne właściwości, używając nazwy klasy, jak pokazano poniżej.

class Greeting extends React.Component {
  render() {
    return (
      <h1>Hello, {this.props.name}</h1>
    );
  }
}

// Specifies the default values for props:
Greeting.defaultProps = {
  name: 'Stranger'
};

Możesz skorzystać z zalecanego sposobu Reacta z tego linku, aby uzyskać więcej informacji

Rohith Murali
źródło
4

Dla funkcji typu prop możesz użyć następującego kodu:

AddAddressComponent.defaultProps = {
    callBackHandler: () => {}
};

AddAddressComponent.propTypes = {
    callBackHandler: PropTypes.func,
};
Wolfack
źródło
3

Jeśli używasz komponentu funkcjonalnego, możesz zdefiniować wartości domyślne w przydziale destrukturyzacji, na przykład:

export default ({ children, id="menu", side="left", image={menu} }) => {
  ...
};
Brian Burns
źródło
0
class Example extends React.Component {
  render() {
    return <h1>{this.props.text}</h1>;
  }
}

Example.defaultProps = { text: 'yo' }; 
Lepkem
źródło