Reageren- Kan eigenschap ‘setState’ van undefined niet lezen

om de een of andere reden krijg ik de foutmelding “React-Cannot read property ‘setState’ of undefined”. Dus this.state wordt nooit bijgewerkt met de waarden die de gebruiker invoert. Toen ik de binding probeerde die is becommentarieerd, krijg ik vreemd gedrag waarbij ik geen invoer voor de gebruikersnaam kan typen en ik niet langer de null-fout krijg, maar de waarden zijn gewoon niet gedefinieerd. Alle hulp zou op prijs worden gesteld. Bedankt.

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);

Antwoord 1, autoriteit 100%

In deze gebeurtenis-handlers is e.targetde <input>die de gebeurtenis heeft geactiveerd.

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 });
}

U krijgt de waarde van een input met behulp van de valueeigenschap:

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

U moet ook controleren thisis goed gebonden, volgens de commentaarcode in uw constructeur.


Als u uw ingangen Geschikt geeft nameROPS, vervangt u deze met een enkele onChangeHandler:

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}/>
  // ...
}

Antwoord 2, Autoriteit 38%

Bewerken

Als u het patroon van binding in de constructor gaat volgen, moet u ervoor zorgen dat u een correcte constructor-aanroep gebruikt:

constructor (props) {
    super(props)

Kennisgeving propsin de constructor.

origineel antwoord

Aangezien het lijkt, gebruikt u ES6-componentdefinities, moet u binden aan thisbinnen de gerenderde component:

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

U hoeft dit spul niet te definiëren in de constructor:

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

Er verschijnt ook dat je misschien een code in je voorbeeld hebt weggelaten, dus ik weet niet zeker of je probeerde de onnodige onderdelen af te ronden omwille van het voorbeeld of wat, maar zorg ervoor dat je component is goed gestructureerd.


Antwoord 3, Autoriteit 6%

Als u een pijl-functie gebruikt, hoeft u niet te binden.

onNameChange = (e)=> {
this.setState({name:e.target.value});
}

onPasswordChange = (e) => {
this.setState({password:e.target.value});
}

Other episodes