Why do you need to import React multiple times in parent and child components?
In nodejs
each file is a module, that has its own scope of variables. When you import variable into file (React
for example) you add this variable to the module scope, but not to the global scope.
In case of webpack
you can use providePlugin
to easily make React
variable global:
new webpack.ProvidePlugin({ React: 'react' // ReactJS module name in node_modules folder})
After that you are able to skip importing React
variable in all of your modules. Webpack
will do it itself where needed.
If you use JSX
and babel
, you have to import React
in every file because babel-preset-react
will transpile your JSX
code into React.createElement()
calls, so this code
const Foo = () => <h1>Test</h1>;
will be
var Foo = function Foo() { return React.createElement( "h1", null, "Test" );};
DEMO: Babel REPL
This is the reason why React
should be accessible in the proper scope and one way to do it, is to import React in a file.
The root of the question is one of dependency management -- how do I, the author, describe and obtain external dependencies I need in my "thing" (application/component/module) for it to do its job?
JavaScript benefits (or suffers) from having a global namespace in which dependencies can be injected. While this can often simplify dependency management in the short term (e.g. you can ignore it and expect everything you need to be available in the global namespace), it can often cause issues as an application grows and changes. For example, given an application with multiple contributors, one might decide to change a part of the application to no longer use a particular dependency and therefore remove it. If another part of the application needed it but that dependency wasn't formally declared anywhere, it could be easily missed.
To do dependency management well, each discrete "thing" should describe its dependencies independent of any other "thing" such that it can be safely used in any given context. This ensures that each "thing" has exactly what it needs no matter how it is used and what its "parent" (the code importing the "thing") has.
An alternative to this approach is dependency injection. In this model, the "thing" provides an interface for passing the dependencies into the "thing" from the consumer. There are flexibility and testability advantages to this which are out of scope of your question. :)
// 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 componentexport default (React, PropTypes) => { return class extends React.Component { static propTypes = { name: PropTypes.string.isRequired } render () { return ( <div /> ); } };};
All of that to say, it is somewhat a "safety measure" to have each "thing" import its own dependencies. It lets you safely refactor your code without the cognitive overhead of remembering what is providing those dependencies.