简体   繁体   中英

Conditionally render empty div or error with React & Bootstrap

I'm setting up a signup form that displays errors below the input fields if the user makes a mistake. The way I have it setup right now, the form will add a div with the error below when the user tries to submit their info. My issue is that when there's an error, it adds the div and messes up the layout of the form because it has to move everything to make space for each error. Is there a way to just have an empty div there if there isn't any errors so that it doesn't mess with the layout when there is one? So like, instead of having margin for spacing between fields, it's an empty div for the errors.

import React, { Component } from "react";
import axios from "axios";
import classnames from "classnames";

import "./Signup.css";

class Signup extends Component {
  constructor() {
    super();
    this.state = {
      username: "",
      email: "",
      password: "",
      errors: {}
    };

    this.onChange = this.onChange.bind(this);
    this.onSubmit = this.onSubmit.bind(this);
  }

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

    const newUser = {
      username: this.state.username,
      email: this.state.email,
      password: this.state.password
    };

    axios
      .post("api/users/register", newUser)
      .then(res => console.log(res.data))
      .catch(err => this.setState({ errors: err.response.data }));
  }

  render() {
    const { errors } = this.state;

    return (
      <div className="signup-form">
        <form noValidate onSubmit={this.onSubmit}>
          <h2>Sign Up</h2>
          <p>It's free and only takes a minute.</p>
          <hr />
          <div className="form-group">
            <label>Username</label>
            <input
              type="text"
              name="username"
              className={classnames("form-control form-control-md", {
                "is-invalid": errors.username
              })}
              value={this.state.username}
              onChange={this.onChange}
            />
            {errors.username && (
              <div className="invalid-feedback">{errors.username}</div>
            )}
          </div>
          <div className="form-group">
            <label>Email</label>
            <input
              type="text"
              name="email"
              className={classnames("form-control form-control-md", {
                "is-invalid": errors.email
              })}
              value={this.state.email}
              onChange={this.onChange}
            />
            {errors.email && (
              <div className="invalid-feedback">{errors.email}</div>
            )}
          </div>
          <div className="form-group">
            <label>Password</label>
            <input
              type="text"
              name="password"
              className={classnames("form-control form-control-md", {
                "is-invalid": errors.password
              })}
              value={this.state.password}
              onChange={this.onChange}
            />
            {errors.password && (
              <div className="invalid-feedback">{errors.password}</div>
            )}
          </div>
          <div className="form-group">
            <button type="submit" className="btn btn-primary btn-block btn-lg">
              Sign Up
            </button>
          </div>
          <p className="small text-center">
            By clicking the Sign Up button, you agree to our <br />
            <a href="#">Terms &amp; Conditions</a>, and{" "}
            <a href="#">Privacy Policy</a>
          </p>
          <div className="text-center">
            Already have an account? <a href="#">Login here</a>
          </div>
        </form>
      </div>
    );
  }
}

export default Signup;

Yes, you can use visibility:hidden property of css.

 <div style={{ visibility: error.email? 'visible': 'hidden'}}></div>

since visibility always takes up space, in both cases it is visible as well as hidden. so it won't mess with the layout.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM