React API Sends Blank Value (Some State Issue)

Viewed 372

I've a login form with Validate() function. I'm trying to send input values to my Django backend but i'm getting response as below. I think the issue is i'm storing my data like " input:{} " but on the App.js i've username and password values. I'm new at React and i'm gonna freak out. I need this validation function. I'm so confused.

{
    "username": [
        "This field may not be blank."
    ],
    "password": [
        "This field may not be blank."
    ]

LoginForm.js (handle_login is a function on my App.js)

import React from 'react';
import PropTypes from 'prop-types';


class LoginForm extends React.Component {

  constructor() {
    super();
    this.state = {
      input: {},
      iderr: false,
      data: null,
      errors: {}
    };
     
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }


         
  checkgiris = (e, data) => {
    e.preventDefault();
    fetch('http://localhost:8000/token-auth/', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(data)
      })  
      .then(respons => {
        if(respons.status === 200){
         this.props.handle_login(e, this.state.input) 
      }
      else {
        this.setState({iderr:true})
       }
    })
    
  };

  handleChange(e) {
    let input = this.state.input;
    input[e.target.name] = e.target.value;
  
    this.setState({
      input
    });
  }

 

  handleSubmit(e) {
    e.preventDefault();
  
    if(this.validate()){
        console.log(this.state);
        let input = {};
        input["username"] = "";
        input["password"] = "";
        this.setState({input:input});
        this.checkgiris(e, this.state.input) 
    }
  }

  validate(){
    
    let input = this.state.input;
    let errors = {};
    let isValid = true;



    if (!input["username"]) {
      isValid = false;
      errors["username"] = "Username may not blank";
    }


    if (!input["password"]) {
      isValid = false;
      errors["password"] = "Password may not blank";
    }


    this.setState({
      errors: errors
    });

    return isValid;
}

  render() {
    return (
     
      <form onSubmit={this.handleSubmit}>
        <center><h4>Login</h4></center>
        <div class="girisformu">
        <input
          class="girisid"
          id="username"
          type="text"
          placeholder="Username"
          name="username"
          value={this.state.input.username}
          onChange={this.handleChange}
        />
         <div className="text-danger">{this.state.errors.username}</div>
        <input
          class="girispw"
          id="password"
          type="password"
          placeholder="Password"
          name="password"
          value={this.state.input.password}
          onChange={this.handleChange}
        />
         <div className="text-danger">{this.state.errors.password}</div>
         { this.state.iderr ? <div className="text-danger">Your username or password is invalid.</div> : null }
                <br/>
        <input class="girisyapbuton" type="submit" value="Login" />

        </div>
      </form>
    
      
    );
  }
}

export default LoginForm;

LoginForm.propTypes = {
  handle_login: PropTypes.func.isRequired
};

App.js (I didn't share unnecessary codes)

function App() {

  const [displayed_form,setDisplayed_form] = useState('');
  const [username,setUsername] = useState('');
  const [logged_in,setLogged_in] = useState(localStorage.getItem('token') ? true : false);

  useEffect(()=>{
    if (logged_in) {
      fetch('http://localhost:8000/api/current_user/', {
        headers: {
          Authorization: `JWT ${localStorage.getItem('token')}`
        }
      })
        .then(res => res.json())
        .then(json => {
          setUsername(json.username);
        });
    }
  },[]) //notice the empty array here


  const handle_login = (e, data) => {
    e.preventDefault();
    fetch('http://localhost:8000/token-auth/', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(data)
    })
      .then(res => res.json())
      .then(json => {
        localStorage.setItem('token', json.token);
        setLogged_in(true);
        setDisplayed_form('');
        setUsername(json.user.username);
      })
      .catch(error => {
        console.log(error)
      })
  };

  

  const handle_signup = (e, data) => {
  
    e.preventDefault();
    fetch('http://localhost:8000/api/users/', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(data)
    })
      .then(res => res.json())
      .then(json => {
        localStorage.setItem('token', json.token);
        setLogged_in(true);
        setDisplayed_form('');
        setUsername(json.username);
      });

  };

  const handle_logout = () => {
    localStorage.removeItem('token');
    setLogged_in(false);
    setUsername('');
  };

  const display_form = form => {
    setDisplayed_form(form);
  };



  let form;
  switch (displayed_form) {
    case 'login':
      form = <div class="giris"><LoginForm handle_login={handle_login} /></div>;
      break;
    case 'signup':
      form = <div class="kayitol"><SignupForm handle_signup={handle_signup} /></div>;
      break;
    default:
      form = null;
  }

return(
<div className="App">
<div>
bla bla bla .......
2 Answers

I've removed these lines

console.log(this.state);
let input = {};
input["username"] = "";
input["password"] = "";
this.setState({input:input});

and it's okay now!

You are reseting the input values before calling checkgiris function. I recommend you to reset the values on API call response or after calling checkgiris:

if(this.validate()){
  this.checkgiris(e, this.state.input);
  //--> reset input values after this
}
Related