Matt
Matt

Reputation: 551

Cannot Get ReactJS Component to Update

I'm attempting to update an area on my page once a fetch() call has been made with the resulting error message from the fetch() call. The fetch() call is executed when the form button is submitted.

When fetch() has completed, I have written ErrorMessage(data['Result']); which I thought would pass data['Result'] as the props. You can see in my render that I have <ErrorMessage error="Original Message" /> which is what I thought would update with the message from the fetch() call.

Please see my full code below for this page:

import React from 'react';
import './css/LoginForm.css';

function ErrorMessage(props) {
    return (
        <p id="error-message">
            {props.error}      
        </p>
    )
}

class LoginForm extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            username: '',
            password: ''
        };

        this.handleInputChange = this.handleInputChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleInputChange(event) {
        const target = event.target;
        const value = target.value;
        const name = target.name;

        this.setState({
            [name]: value
        });
    }

    handleSubmit(event) {
        event.preventDefault();
        var loginData = {
            username: this.state.username,
            password: this.state.password
        }

        fetch('/login', {
            method: 'POST',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                loginData: loginData
            })
        })
        .then(function(response) {
            return response.json();
        })
        .then(function(data) {
            if (data['Result']) {
                console.log(data['Result']);
                ErrorMessage(data['Result']);
            }
        })
        .catch(function(error) {
            console.log('Error: ', error);
        });
    }

    render() {
        return (
            <div id="login-form-container">
                <form id="login-form" onSubmit={this.handleSubmit} method="POST">
                    <ErrorMessage error="Original Message" />
                    <input
                        type="text"
                        name="username"
                        placeholder="username"
                        autoComplete="username"
                        onFocus={(e) => e.target.placeholder = ''}
                        onBlur={(e) => e.target.placeholder = 'username'}
                        value={this.state.username}
                        onChange={this.handleInputChange}
                        required
                    ></input>
                    <input
                        type="password"
                        name="password"
                        placeholder="password"
                        autoComplete="current-password"
                        onFocus={(e) => e.target.placeholder = ''}
                        onBlur={(e) => e.target.placeholder = 'password'}
                        value={this.state.password}
                        onChange={this.handleInputChange}
                        required
                    ></input>
                    <button type="submit" name="submit">Login</button>
                    <p className="forgotten-password">Forgotten your password?</p>
                </form>
            </div>
        );
    }

}

export default LoginForm;

This may be completely wrong as I am struggling to understand exactly how a component works in ReactJS, so I apologise in advance. Thank you for any insight.

Upvotes: 2

Views: 58

Answers (1)

Tholle
Tholle

Reputation: 112777

Creating a component when your fetch is complete will not affect what is returned from the render method of your LoginForm component.

You could instead set the error message in the LoginForm state, and use that as props for the ErrorMessage component in the render method.

Example

class LoginForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      username: "",
      password: "",
      error: "Original Message"
    };

    this.handleInputChange = this.handleInputChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  // ...

  handleSubmit(event) {
    event.preventDefault();
    var loginData = {
      username: this.state.username,
      password: this.state.password
    };

    fetch("/login", {
      method: "POST",
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json"
      },
      body: JSON.stringify({
        loginData: loginData
      })
    })
      .then((response) => {
        return response.json();
      })
      .then((data) => {
        if (data["Result"]) {
          console.log(data["Result"]);
          this.setState({ error: data["Result"] });
        }
      })
      .catch((error) => {
        console.log("Error: ", error);
      });
  }

  render() {
    return (
      <div id="login-form-container">
        <form id="login-form" onSubmit={this.handleSubmit} method="POST">
          <ErrorMessage error={this.state.error} />
          <input
            type="text"
            name="username"
            placeholder="username"
            autoComplete="username"
            onFocus={e => (e.target.placeholder = "")}
            onBlur={e => (e.target.placeholder = "username")}
            value={this.state.username}
            onChange={this.handleInputChange}
            required
          />
          <input
            type="password"
            name="password"
            placeholder="password"
            autoComplete="current-password"
            onFocus={e => (e.target.placeholder = "")}
            onBlur={e => (e.target.placeholder = "password")}
            value={this.state.password}
            onChange={this.handleInputChange}
            required
          />
          <button type="submit" name="submit">
            Login
          </button>
          <p className="forgotten-password">Forgotten your password?</p>
        </form>
      </div>
    );
  }
}

Upvotes: 2

Related Questions