Bad ways you’re using react – Large Components

Share This Post

Something I see a lot when inheriting projects from previous teams is the use of large components. Files with 500+, 1k+ or even 2k+ lines, aren’t uncommon. It makes inheriting a project a lot harder since it’s hard to follow what’s going on.

Here’s what I’ve learned after handling more than a handful of large components.

Why are large components bad

There’s three main reasons why large components are bad practice in react. A quick query on ChatGPT summarizes it pretty well.

  1. Performance: One of the primary reasons to avoid large components in React is performance. Large components can lead to a slower rendering process, resulting in a less responsive application. When a component becomes too large, it may take longer to render, leading to a decrease in overall performance.
  2. Reusability: Another reason to avoid large components in React is reusability. Large components often have many responsibilities and are difficult to reuse in different parts of the application. Small components, on the other hand, are easier to reuse, making them more flexible and adaptable.
  3. Maintainability: Finally, large components can be more difficult to maintain. When a component becomes too large, it can be challenging to understand and modify its behavior. Breaking a large component into smaller ones can help make it easier to maintain over time, as each smaller component can be more easily understood and modified independently.

An Example — Bad Code

import React, { Component } from 'react';

class LargeFormComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      firstName: '',
      lastName: '',
      email: '',
      phone: '',
      address: '',
      city: '',
      state: '',
      zipCode: '',
      errors: {}
    };
  }

  handleChange = e => {
    const { name, value } = e.target;
    this.setState({ [name]: value });
  };

  handleSubmit = e => {
    e.preventDefault();
    const { firstName, lastName, email, phone, address, city, state, zipCode } = this.state;
    // validation logic goes here
    // form submission logic goes here
  };

  render() {
    const { firstName, lastName, email, phone, address, city, state, zipCode, errors } = this.state;
    return (
      <form onSubmit={this.handleSubmit}>
        <label htmlFor="firstName">First Name:</label>
        <input type="text" id="firstName" name="firstName" value={firstName} onChange={this.handleChange} />
        {errors.firstName && <div className="error">{errors.firstName}</div>}

        <label htmlFor="lastName">Last Name:</label>
        <input type="text" id="lastName" name="lastName" value={lastName} onChange={this.handleChange} />
        {errors.lastName && <div className="error">{errors.lastName}</div>}

        <label htmlFor="email">Email:</label>
        <input type="email" id="email" name="email" value={email} onChange={this.handleChange} />
        {errors.email && <div className="error">{errors.email}</div>}

        <label htmlFor="phone">Phone:</label>
        <input type="tel" id="phone" name="phone" value={phone} onChange={this.handleChange} />
        {errors.phone && <div className="error">{errors.phone}</div>}

        <label htmlFor="address">Address:</label>
        <input type="text" id="address" name="address" value={address} onChange={this.handleChange} />
        {errors.address && <div className="error">{errors.address}</div>

        <label htmlFor="city">City:</label>
        <input type="text" id="city" name="city" value={city} onChange={this.handleChange} />
        {errors.city && <div className="error">{errors.city}</div>}

        <label htmlFor="state">State:</label>
        <input type="text" id="state" name="state" value={state} onChange={this.handleChange} />
        {errors.state && <div className="error">{errors.state}</div>}

        <label htmlFor="zipCode">Zip Code:</label>
        <input type="text" id="zipCode" name="zipCode" value={zipCode} onChange={this.handleChange} />
        {errors.zipCode && <div className="error">{errors.zipCode}</div>}

        <button type="submit">Submit</button>
      </form>
    );
  }
}

export default LargeFormComponent;

Solution — Good Code

import React, { Component } from 'react';
import Input from './Input';

class LargeFormComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      firstName: '',
      lastName: '',
      email: '',
      phone: '',
      address: '',
      city: '',
      state: '',
      zipCode: '',
      errors: {}
    };
  }

  handleChange = e => {
    const { name, value } = e.target;
    this.setState({ [name]: value });
  };

  handleSubmit = e => {
    e.preventDefault();
    const { firstName, lastName, email, phone, address, city, state, zipCode } = this.state;
    // validation logic goes here
    // form submission logic goes here
  };

  render() {
    const { firstName, lastName, email, phone, address, city, state, zipCode, errors } = this.state;
    return (
      <form onSubmit={this.handleSubmit}>
        <Input label="First Name" name="firstName" value={firstName} onChange={this.handleChange} error={errors.firstName} />
        <Input label="Last Name" name="lastName" value={lastName} onChange={this.handleChange} error={errors.lastName} />
        <Input label="Email" name="email" value={email} onChange={this.handleChange} error={errors.email} />
        <Input label="Phone" name="phone" value={phone} onChange={this.handleChange} error={errors.phone} />
        <Input label="Address" name="address" value={address} onChange={this.handleChange} error={errors.address} />
        <Input label="City" name="city" value={city} onChange={this.handleChange} error={errors.city} />
        <Input label="State" name="state" value={state} onChange={this.handleChange} error={errors.state} />
        <Input label="Zip Code" name="zipCode" value={zipCode} onChange={this.handleChange} error={errors.zipCode} />
        <button type="submit">Submit</button>
      </form>
    );
  }
}

export default LargeFormComponent;

import React from 'react';

const Input = ({ label, name, value, onChange, error }) => {
  return (
    <div>
      <label htmlFor={name}>{label}:</label>
      <input type="text" id={name} name={name} value={value} onChange={onChange} />
      {error && <div className="error">{error}</div>}
    </div>
  );
};

export default Input;

Leave a Reply

Digital art dealers

Join our vibrant community of more than 750 members by subscribing to our newsletter. Every Monday, you'll receive a programming meme to kickstart your week.

follow us on

© 2023 Digital Art Dealers. All rights reserved.

%d bloggers like this: