2016-12-13 1 views
1

Ich versuche, eine einfache Todo-App zu erstellen, löst jedoch einen Fehler aus: Bitte kann jemand helfen, den Fehler zu identifizieren?Nicht zu erkennen this.state.data in ReactJs App

Fehler

app.min.js:9 Uncaught TypeError: Cannot read property 'data' of undefined at Object.value [as addNewContact] (http://localhost:8888/dist/assets/js/app.min.js:9:18059) at b.value (http://localhost:8888/dist/assets/js/app.min.js:9:19043) at Object.f.invokeGuardedCallback (http://localhost:8888/dist/assets/js/app.min.js:3:5790) at g (http://localhost:8888/dist/assets/js/app.min.js:3:3021) at Object.h [as executeDispatchesInOrder] (http://localhost:8888/dist/assets/js/app.min.js:3:3241) at l (http://localhost:8888/dist/assets/js/app.min.js:2:30755) at n (http://localhost:8888/dist/assets/js/app.min.js:2:30881) at Array.forEach (native) at c (http://localhost:8888/dist/assets/js/app.min.js:3:6210) at Object.processEventQueue (http://localhost:8888/dist/assets/js/app.min.js:2:31947

Code:

import React from 'react'; 
import ReactDOM from 'react-dom'; 


export class ContactsListApp extends React.Component { 
    constructor(props) { 
     super(props); 
     this.state = { 
      data: this.props.data 
     } 
    } 
    addContact(newContactObj) { 
     console.log(newContactObj); 
     var tmpStateData = this.state.data; 
     tmpStateData.push(newContactObj.value); 

     this.setState({ 
      data: tmpStateData 
     }); 
    } 
    render() { 
     return (
      <div className="contact-list"> 
       <div className="container"> 
        <div className="row"> 
         <div className="col-xs-12 col-sm-12 col-md-12"> 
          <AddContactPanel addNewContact={this.addContact} /> 
          <ContactList contacts={this.state.data} /> 
         </div> 
        </div> 
       </div> 
      </div> 
     ) 
    } 
} 

class ContactList extends React.Component { 
    render() { 
     var items = Array.prototype.map.call(this.props.contacts, function (contact, index) { 
      return <ContactItem name={contact.name} key={index} /> 
     }); 

     return (
      <ul>{items}</ul> 
     ) 
    } 
} 

class AddContactPanel extends React.Component { 
    constructor(props) { 
     super(props); 
    } 
    handleAddContact() { 
     var contactItem = this.refs.newContactName; 
     this.props.addNewContact({ 
      "_id": (Math.random(1000 * 10) + 1), 
      "name": this.refs.newContactName.value, 
      "occupation": "myJob", 
      "email": "[email protected]", 
      "telephone": "" 
     }); 
    } 
    render() { 
     return (
      <div className="row"> 
       <form> 
        <input required ref="newContactName" type="text" name="newContactName" /> 
        <input type="submit" name="submit" onClick={this.handleAddContact.bind(this)} /> 
       </form> 
      </div> 
     ) 
    } 
} 


class ContactItem extends React.Component { 
    render() { 
     return (
      <li>{this.props.name}</li> 
     ) 
    } 
} 


module.exports = { 
    contactListApp: ContactsListApp 
} 

Vielen Dank im Voraus!

+3

Set 'this' für' addContact' gesetzt - 'this.addContact.bind (this)' –

+1

Auch in Ihrem 'constructor' die Anfangs Wert des 'Daten'-Schlüssels innerhalb des Zustandes sollte auf' props.data' und nicht auf 'this.props.data' gesetzt werden – juandemarco

Antwort

1

Zuerst, um den Status für die Funktion zur Verfügung zu stellen, die Sie binden müssen. Sie können zu diesem Zweck

addContact(newContactObj) { 
     console.log(newContactObj); 
     var tmpStateData = this.state.data; 
     tmpStateData.push(newContactObj.value); 

     this.setState({ 
      data: tmpStateData 
     }); 
    } 

Zweitens Verwendung von Fett-Pfeil-Funktion machen: in den Anfangszustand Einstellung Requisiten ist ein Anti-Muster, wie durch react docs vorgeschlagen, und Sie sollen mit ihm auf diese Weise vermeiden. Stattdessen können Sie den Zustand in einen Prop-Wert in der componentDidMount Funktion wie

constructor(props) { 
    super(props); 
    this.state = { 
     data: '' 
    } 
} 
componentDidMount() { 
    this.setState({data: this.props.data}) 
} 
addContact = (newContactObj) => { 
    console.log(newContactObj); 
    var tmpStateData = this.state.data; 
    tmpStateData.push(newContactObj.value); 

    this.setState({ 
     data: tmpStateData 
    }); 
} 
+0

Danke, es funktioniert - geschätzt! Muss ich dicke Pfeile benutzen? Es wäre großartig, wenn ich es ohne seinen Einsatz zeigen würde, alternative Techniken, um das gleiche Ergebnis zu erreichen. – vicgoyso

+0

Ja, Sie können die Funktion im Konstruktor wie binden. 'this.addContact = this.addContact.bind (this)' –