Когда я наследую проекты от предыдущих команд, я часто наблюдаю использование больших компонентов. Файлы с 500+, 1k+ или даже 2k+ строк не редкость. Это значительно усложняет наследование проекта, поскольку трудно следить за тем, что происходит.

Вот что я узнал после обработки более чем нескольких крупных компонентов.

Чем плохи большие компоненты

Есть три основные причины, по которым большие компоненты — это плохая практика в React. Быстрый запрос на ChatGPT довольно хорошо резюмирует это.

  1. Производительность. Одной из основных причин, по которой в React следует избегать больших компонентов, является производительность. Большие компоненты могут привести к замедлению процесса рендеринга, что приведет к снижению отклика приложения. Когда компонент становится слишком большим, рендеринг может занять больше времени, что приводит к снижению общей производительности.
  2. Повторное использование. Еще одна причина, по которой в React следует избегать больших компонентов, — возможность повторного использования. У больших компонентов часто много обязанностей, и их сложно повторно использовать в разных частях приложения. С другой стороны, небольшие компоненты легче использовать повторно, что делает их более гибкими и адаптируемыми.
  3. Удобство обслуживания. Наконец, большие компоненты сложнее обслуживать. Когда компонент становится слишком большим, может быть сложно понять и изменить его поведение. Разбивка крупного компонента на более мелкие может помочь упростить его обслуживание с течением времени, поскольку каждый меньший компонент легче понять и модифицировать независимо друг от друга.

Пример — плохой код

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;

Решение — хороший код

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;

Об авторе

Спасибо за прочтение! Если вы фрилансер и хотите улучшить свою игру по написанию предложений и привлечь больше клиентов, попробуйте Бинго. Зайдите на наш веб-сайт, чтобы узнать больше и начать писать выигрышные предложения уже сегодня.