Зачем вам нужно несколько раз импортировать React в родительском и дочернем компонентах?

Если у вас есть родительский компонентный файл, который уже импортирует React, почему любой из его файлов с обработанными детьми также должен импортировать React? Это всего лишь мера безопасности, если эти дети когда-либо оказываются где-то в другом месте, где React еще не был импортирован?

Ответ 1

В nodejs каждый файл является модулем, который имеет свой собственный диапазон переменных. Когда вы импортируете переменную в файл (например, React), вы добавляете эту переменную в область модуля, но не в глобальную область.

В случае webpack вы можете использовать providePlugin, чтобы легко сделать переменную React global:

new webpack.ProvidePlugin({
  React: 'react' // ReactJS module name in node_modules folder
})

После этого вы можете пропустить импорт переменной React во всех своих модулях. webpack сделает это сам, когда это необходимо.

Ответ 2

Если вы используете JSX и babel, вам нужно импортировать React в каждый файл, потому что babel-preset-react преобразует ваш код JSX в вызовы React.createElement(), поэтому этот код

const Foo = () => <h1>Test</h1>;

будет

var Foo = function Foo() {
  return React.createElement(
    "h1",
    null,
    "Test"
  );
};

DEMO: Babel REPL

Именно поэтому React должен быть доступен в правильной области и одним из способов сделать это, это импортировать React в файл.

Ответ 3

Причина заключается в том, чтобы избежать ненужного скомпилированного кода JavaScript, который вам не нужно компилировать jsx. Например, у вас есть файл, который имеет функцию для добавления или любую функцию, которая не нуждается в компиляции jsx, тогда вы не ставите import React from 'react' в верхней части этот файл. Это позволит сэкономить время компиляции.

Ответ 4

Корень вопроса - это управление зависимостями - как я, автор, описываю и получаю внешние зависимости, которые мне нужны в моей "вещи" (приложение/компонент/модуль), чтобы он выполнял свою работу?

Преимущества JavaScript (или страдает) от наличия глобального пространства имен, в которое могут быть введены зависимости. Хотя это может часто упрощать управление зависимостями в краткосрочной перспективе (например, вы можете игнорировать его и ожидать, что все, что вам нужно, доступно в глобальном пространстве имен), оно часто может вызывать проблемы по мере того, как приложение растет и изменяется. Например, при использовании приложения с несколькими вкладчиками можно решить изменить часть приложения, чтобы больше не использовать определенную зависимость и, следовательно, удалить ее. Если нужна другая часть приложения, но эта зависимость не была официально объявлена ​​нигде, ее можно было бы легко пропустить.

Для правильного управления зависимостями каждая отдельная "вещь" должна описывать свои зависимости независимо от любой другой "вещи", чтобы ее можно было безопасно использовать в любом конкретном контексте. Это гарантирует, что каждая "вещь" имеет то, что ей нужно, независимо от того, как она используется, и что ее "родитель" (код, импортирующий "вещь" ) имеет.

Альтернативой этому подходу является инъекция зависимостей. В этой модели "вещь" предоставляет интерфейс для передачи зависимостей в "вещь" от потребителя. Для этого есть гибкость и возможности тестирования, которые выходят за рамки вашего вопроса.:)

// export a function that expects the React and PropTypes
// dependencies to be injected as parameters and returns
// the component rather than importing the dependencies
// and exporting the component
export default (React, PropTypes) => {
  return class extends React.Component {
    static propTypes = {
      name: PropTypes.string.isRequired
    }
    render () {
      return (
        <div />
      );
    }
  };
};

Все это означает, что это "мера безопасности", чтобы каждая "вещь" импортировала свои собственные зависимости. Это позволяет вам безопасно реорганизовать ваш код без когнитивных издержек, помня о том, что обеспечивает эти зависимости.