If you have a parent component file that already imports React
, why does any of its rendered children files also need to import React? Is it just a safety measure in case those children are ever rendered somewhere else where React has not been imported yet?
问题:
回答1:
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.
回答2:
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.
回答3:
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 component
export 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.
回答4:
The reason is to avoid unnecessary compiled a JavaScript code that you don't have to compile jsx. For example, you have a file that have a function to do adding, or whatever function that doesn't need to compile jsx, then you don't put import React from 'react' on the top of that file. This will save you compile time.