1

I can access this.state outside of fetch,but when trying to access state inside fetch, I get this error:

Uncaught TypeError: Cannot read property 'state' of null

I looked through other posts on StackOverflow, but didn't find a working solution to use the state properties in the fetch call. Please help.

class SignIn extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      email: '',
      password: ''
    }
    this.handleValueChange = this.handleValueChange.bind(this);
  }

  handleValueChange(event) {
    const property = event.target.name;
    this.setState({[property]: event.target.value});
  }

  handleLogin(event){
    event.preventDefault();

    fetch("http://localhost:3001/login.json", {
        method: "POST",
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          email: this.state.email,  //this is where the error occurs
          password: '123456'
        })
    })
    .then(function(res){return res.json();})
    .then(function(data){console.log(data)});
  }

  render() {
    return(
      <header>
        <NavigationBar />

        <div className="form-box">
          <form onSubmit={this.handleLogin}>
            <h2>Login</h2>
            <br />
            <div className="row">
              <div>
                <label>Email</label>
                <input type="text" name="email" ref='emailInputField' 
                  onChange={(event) => this.handleValueChange(event)}
                  required
                />
              </div>
            </div>
            <br />
            <div className="row">
              <div>
                <label>Password</label>
                <input type="text" name="password"
                  onChange={(event) => this.handleValueChange(event)}
                  required
                />
              </div>
            </div>
            <br />
            <div className="btn-submit">
              <input type="submit" value="Let's go!" />
            </div>
          </form>
          <button onClick={() => console.log("this.state", this.state)} >Show state</button>
        </div>
      </header>
    )
  }
}

NOTE: some code not shown for brevity

2
  • 1
    forgot to bind handleLogin method, put this line in constructor: this.handleLogin = this.handleLogin.bind(this) Commented Aug 27, 2017 at 17:38
  • You can't access state there. Pass that value in as a param, a prop, etc. Commented Aug 27, 2017 at 17:39

3 Answers 3

1

Have you tried something like this:

handleLogin = (event) => {
    event.preventDefault();

    fetch("http://localhost:3001/login.json", {
        method: "POST",
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          email: this.state.email,  //this is where the error occurs
          password: '123456'
        })
    })
    .then((res) => {return res.json();})
    .then((data) => {console.log(data)});
  }

Or just bind your function to your component like suggested in the comments and like you already did with your other function. Arrow functions are a lot smoother though.

Sign up to request clarification or add additional context in comments.

2 Comments

I previously tried arrow function without param, but your solution worked! Thank you!
But this is not right approach because unnecessary introducing anonymous block so adding 'handleLogin' in the constructor is the correct way to bind the current object.
1

Add this.handleLogin in the constructor like below.

 constructor(props){
    super(props);
    this.state = {
      email: '',
      password: ''
    }
    this.handleValueChange = this.handleValueChange.bind(this);
    this.handleLogin = this.handleLogin.bind(this)
  }

Comments

0

I think the following should work.

In the line above fetch(...) add const self = this; and call self.state.email.

Let me know if it does.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.