React native: this.setState non è una function

Vedo una serie di domande relative a questo stesso problema, ma sembra che non corrisponda alla questione che ho e sono un po 'più complesse.

Sono in procinto di imparare ReactJS e React Native. Sto nel mezzo di leggere e seguire gli esempi di codice del libro "Learning React Native" qui: https://github.com/bonniee/learning-react-native

Per qualche motivo, denominando this.setState nel codice riportto di seguito quando viene chiamata la function handleTextChange, causa "questo.SetState non è una function". errore. La mia domanda è perché? A differenza di altre domande su questo stesso problema, non credo che la mia chiamata a questo.stateState sia sepolto in una function di richiamata o se istruzione. Perché è indefinito?

Ecco il mio codice:

class WeatherProject extends Component { constructor(props) { super(props); this.state = { zip: "", forecast: null }; } _handleTextChange(event) { this.setState({zip: event.nativeEvent.text}); } render() { return ( <View style={styles.container}> <Text style={styles.welcome}> You input {this.state.zip}. </Text> <TextInput style={styles.input} onSubmitEditing={this._handleTextChange}/> </View> ); } } 

Non utilizzare il binding all'interno di un render. il legame è un funzionamento piuttosto costoso e deve avvenire solo una volta. hai due opzioni:

sia bind la function nel constructor:

 this._handleTextChange = this._handleTextChange.bind(this); 

o utilizzare la function freccia:

 onSubmitEditing={(e) => this._handleTextChange(e)} /> 

Modifica

Apparentemente la freccia funzioni all'interno render è anche una ctriggers pratica (Thx a Adam Terlson nei commenti e risposta in seguito). È ansible leggere eslint docs che afferma:

Una chiamata di chiamata o una freccia in un prop JSX creerà una nuova function su each singolo rendering. Questo è pessimo per le performance, in quanto ciò comporterà il richiamo del collettore di rifiuti più che necessario.

Utilizzando le funzioni di freccia non è ovvio che non si utilizza il legame, ma va comunque evitato.

Il problema è legato al context, come identificato negli altri commenti e risposte qui.

Tuttavia, la prestazione del legame stesso non è un problema. Il modo più rilevante è che l'utilizzo di legami o frecce nei methods di rendering crea una nuova function su ciascun rendering, con conseguente modifica dei puntelli per il bambino che li riceve, forzando una ri-rendering.

Hai due opzioni valide:

 class WeatherProject extends Component { constructor(props) { super(props); this._handleTextChange = this._handleTextChange.bind(this); } // ... } 

Oppure puoi utilizzare la notazione delle properties; di class e assegnare le frecce se si utilizza il plugin babel per esso.

 class WeatherProject extends Component { constructor(props) { super(props); // ... } handleTextChange = (event) => { this.setState({zip: event.nativeEvent.text}); } // ... } 

Vi raccommand vivamente di utilizzare il pacchetto eslint con le regole consigliate di triggerszione triggerste. Cattura gli errori come l'utilizzo di legami / frecce nel tuo rendering, oltre a dirvi che le funzioni prefissate di sottolineatura sono brutte e totalmente non necessarie in React. 🙂