2015-11-29 16 views
9

per qualche motivo, ricevo l'errore "React- Impossibile leggere la proprietà 'setState' di undefined". Quindi questo stato non viene mai aggiornato con i valori immessi dall'utente. Quando ho provato l'associazione che è stata commentata, ho un comportamento strano in cui non riesco a digitare l'input per il nome utente e non ottengo più l'errore nullo, ma i valori sono solo indefiniti. Qualsiasi aiuto sarebbe apprezzato. Grazie.React- Impossibile leggere la proprietà 'setState' di undefined

import __fetch from "isomorphic-fetch"; 
import React from "react"; 
import InlineCss from "react-inline-css"; 
import Transmit from "react-transmit"; 

import Header from './components/header' 

class Registration extends React.Component { 

    componentWillMount() { 
     if (__SERVER__) { 
      console.log("Hello server from Registration"); 
     } 

     if (__CLIENT__) { 
      console.log("Hello Registration screen"); 
     } 
    } 

    constructor() { 
     super() 

     this.state = { 
      name: '', 
      password: '' 
     } 

     //this.onChangeName = this.onChangeName.bind(this); 
     //this.onChangePassword = this.onChangePassword.bind(this); 
    } 

    onChangeName(e) { 
     //this.state.name = e.target.name 
     this.setState({ name: e.target.name}); 
    } 

    onChangePassword(e) { 
     //this.state.password = e.target.name 
     this.setState({ password: e.target.password }); 
    } 


    emptinessChecker(){ 
     let {name, password} = this.state 
     console.log(name) 
     if (name === "" || password === "") { 
      return true; 
     } 
     else { 
      return false; 
     } 
    } 

    submit() { 
     console.log(this) 
     console.log(this.state) 
     if (this.emptinessChecker()){ 
      alert("Please do not leave any fields blank!"); 
     } 
     else{ 
      var xhr = new XMLHttpRequest(); // new HttpRequest instance 
      xhr.open("POST", "/edit"); 
      xhr.addEventListener("load", e => { 
       console.log(xhr.responseText) 
      }); 

      xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); 
      xhr.send(JSON.stringify(this.state)); 
      window.location.href= "/success" 
     } 
    } 


    render() { 

     //let {username, password} = this.state 

     if (__SERVER__) { 
      console.log("render server from registration"); 
     } 
     if (__CLIENT__) { 
      console.log('we client now!') 
     } 

     return (
      <InlineCss stylesheet={Registration.css()} namespace="Registration"> 
       <Header /> 



       <div> 
        <div className = "Register" > 
         Register 
        </div> 


        <ul className="account-fields"> 

         <div className = 'Name'> 
           <label>Username</label> 
           <input type="text" value={this.state.name} onChange={this.onChangeName} /> 
         </div> 

         <div className = 'Password'> 
           <label>Password</label> 
           <input type="password" value={this.state.password} onChange={this.onChangePassword} /> 
         </div> 


         <div className='submitForm'> 
          <div className='submit' onClick={e=>this.submit()}>Submit</div> 
         </div> 

        </ul> 
       </div> 

      </InlineCss> 




     ); 
    } 
    /** 
    * <InlineCss> component allows you to write a CSS stylesheet for your component. Target 
    * your component with `&` and its children with `& selectors`. Be specific. 
    */ 
    static css() { 
     return (` 
      & .Register { 
       position: fixed; 
       right: 550px; 
       bottom: 550px; 
       font-size: 50px; 
      } 
      & .account-fields { 
       position: fixed; 
       right: 550px; 
       bottom: 450px; 
       font-size: 20px; 
      } 
      & .submitForm { 
       position: fixed; 
       right: 10px; 
       bottom: 10px; 
       width: 200px; 
      } 
      & .submit { 
       cursor: pointer; 
       text-align: center; 
       font-size: 20px; 
       padding: 10px; 
       background-color: #00E4A5; 
       color: #fff; 
       border-radius: 5px; 
       box-shadow: 0 2px 10px 0 rgba(0,0,0,.13); 
       border-bottom: 2px solid #00C791; 
       text-shadow: 0px -1px 0px #009E73; 
      } 
     `); 
    } 

} 

export default Transmit.createContainer(Registration); 
+0

Perché stai cercando di impostare tali metodi nel costruttore se esistono già come parte del definizione di classe? –

+0

http://stackoverflow.com/questions/32317154/uncaught-typeerror-cannot-read-property-setstate-of-undefined – user3708762

risposta

5

modificare

Se avete intenzione di seguire il modello di legare nel costruttore, assicurarsi di utilizzare una corretta costruttore di invocazione:

constructor (props) { 
    super(props) 

Avviso props all'interno del costruttore.

risposta originale

Poiché sembra che si sta utilizzando le definizioni dei componenti ES6, si dovrebbe legarsi alla this all'interno del componente reso:

<input type="text" value={this.state.name} onChange={this.onChangeName.bind(this)} /> 

Non è necessario definire questa roba nel costruttore :

//this doesn't work 
//this.onChangeName = this.onChangeName.bind(this); 
//this.onChangePassword = this.onChangePassword.bind(this); 

sembra anche che forse hai lasciato fuori qualche codice nel tuo esempio, quindi non sono sicuro se si stava tentando di sbarazzarsi di le parti non necessarie a titolo di esempio o cosa, ma assicurati che il tuo componente sia strutturato correttamente.

+0

Anche in questo caso si verifica uno stato indefinito durante l'aggiornamento. – Nickvda

13

In questi gestori di eventi, e.target è il <input> che ha attivato l'evento.

onChangeName(e) { 
    //this.state.name = e.target.name 
    this.setState({ name: e.target.name}); 
} 

onChangePassword(e) { 
    //this.state.password = e.target.name 
    this.setState({ password: e.target.password }); 
} 

si ottiene un valore di un ingresso utilizzando la sua proprietà value:

onChangeName(e) { 
    this.setState({name: e.target.value}); 
} 

onChangePassword(e) { 
    this.setState({password: e.target.value}); 
} 

È inoltre necessario garantire this è legato correttamente, secondo il codice commentato-out nel costruttore.


Se si danno i ingressi adatti name oggetti di scena, si sostituisce questi con un unico onChange handler:

constructor(props) { 
    super(props) 
    // ... 
    this.onChange = this.onChange.bind(this) 
} 

onChange(e) { 
    this.setState([e.target.name]: e.target.value}) 
} 

render() { 
    // ... 
    <input type="text" name="name" value={this.state.name} onChange={this.onChange}/> 
    <input type="password" name="password" value={this.state.password} onChange={this.onChange}/> 
    // ... 
} 
Problemi correlati