Обновление. Поскольку крючки широко распространены, вам не следует применять этот шаблон. Вместо этого вам следует использовать крючки.

Несомненно, самый большой источник путаницы для начинающих разработчиков JavaScript - это ключевое слово this. Это потому, что даже если вы ожидаете, что this будет представлять объект, из которого он вызывается, это не всегда так.

Понять, какую ценность принимает это, не так уж сложно. И действительно, единственный раз, когда вы должны осознавать, что он берет на себя то, чего вы не ожидаете, - это когда он используется в обратном вызове. Поэтому все, что вам нужно сделать, это не забыть привязать this к функциям обратного вызова и забыть, что я когда-либо поднимал эту тему.

Но настоящая проблема заключается не в написании кода JavaScript и не в том, чтобы он сразу сломался. Он читает чужой код и может понять, что пытается сделать. почти всегда будет выглядеть неоднозначно даже для опытного глаза. И если вам нужно всего лишь 0,1% объема вашего черепа, чтобы рассуждать о том, о чем идет речь, что ж, тогда это уже слишком. Просто должно быть сразу очевидно, что пытается сделать фрагмент кода, или, по крайней мере, настолько ясно, насколько это технически возможно.

Давайте посмотрим на очень простую форму в React:

class CreatePost extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      subject: "",
      body: ""
    };
    this.handleChange = this.handleChange.bind(this);
  }
  handleChange(event) {
    this.setState({[event.target.name]: event.target.value});
  }
  handleSubmit(event) {
    //logic for saving post here
  }
  componentDidMount() {
    //maybe some lifecycle action here
  }
  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          <input 
            type="text" 
            placeholder="Subject" 
            value={this.state.subject}
            name="subject"
            onChange={this.handleChange} />
        </label>
        <label>
          <textarea 
            value={this.state.body}
            name="body"
            onChange={this.handleChange}>
          </textarea>
        </label>
      </form>
    )
  }
}

Это не так уж и плохо. В основном просто раздражает то, что вам нужно написать «this.handleChange = this.handleChange.bind (this);» вверх в конструкторе. В качестве альтернативы вы можете писать компоненты React традиционным способом, используя createReactClass, который автоматически связывает this. Но опять же, дело не в том, что вам нужно писать больше или меньше кода, а в том, что может быть, по крайней мере, немного сложнее понять, что делает код.

Хорошо, время для того, чего я пытался достичь: более четкого способа написания компонентов React. Взглянем:

function CreatePost(props) {
  const component = new React.Component(props);
  component.state = {
    subject: "",
    body: ""
  };
  function handleChange(event) {
    component.setState({[event.target.name]: event.target.value});
  }
  function handleSubmit(event) {
    //logic for saving post here
  }
  component.componentDidMount = function() {
    //some lifecycle action here
  }
  component.render = function() {
    return (
      <form onSubmit={handleSubmit}>
        <label>
          <input 
            type="text" 
            placeholder="Subject" 
            value={component.state.subject}
            name="subject"
            onChange={handleChange} />
        </label>
        <label>
          <textarea 
            value={component.state.body}
            name="body"
            onChange={handleChange}>
          </textarea>
        </label>
      </form>
    )
  }
  return component;
}

Больше нет этого, и здесь все работает как положено. Вы по-прежнему можете использовать Redux или любые другие компоненты более высокого порядка.

Что тут происходит? Вы просто создаете экземпляр React.Component внутри функции, а затем в конечном итоге возвращаете этот экземпляр после того, как расширили его.

Главное отличие, по крайней мере, на мой взгляд, совершенно ясно, что все делает. Какое состояние вы устанавливаете? Компонент конечно. Вы только расширяете жизненный цикл компонента и методы рендеринга. Все остальные ваши функции являются лишь частью функции обертывания, но все равно работают из-за магии закрытия.

Если вы использовали Паразитарное наследование, все это должно быть вам знакомо.

Сможет ли написание таких компонентов React увеличить продуктивность в 10 раз? Нет. А как насчет повышения на 10%? Возможно нет.

Тем не менее, для более крупных и сложных компонентов должно стать яснее, к чему все относится, а также помочь разработчикам, которые плохо знакомы с React или JavaScript, понять, как работает React. И, честно говоря, я не вижу серьезных недостатков в этом.