【发布时间】:2017-11-08 08:08:51
【问题描述】:
如果你有一个已经导入 React 的父组件文件,为什么它的任何渲染的子文件也需要导入 React?这是否只是一种安全措施,以防这些孩子被渲染到尚未导入 React 的其他地方?
【问题讨论】:
如果你有一个已经导入 React 的父组件文件,为什么它的任何渲染的子文件也需要导入 React?这是否只是一种安全措施,以防这些孩子被渲染到尚未导入 React 的其他地方?
【问题讨论】:
问题的根源在于依赖管理——作为作者,我如何在我的“事物”(应用程序/组件/模块)中描述和获取我需要的外部依赖项以使其完成工作?
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 />
);
}
};
};
总而言之,让每个“事物”导入自己的依赖项在某种程度上是一种“安全措施”。它使您可以安全地重构代码,而无需记住提供这些依赖项的认知开销。
【讨论】:
原因是为了避免不必要的编译一段你不必编译jsx的JavaScript代码。例如,你有一个文件需要添加一个函数,或者任何不需要编译 jsx 的函数,那么你不要把 import React from 'react' 放在那个文件。这将节省您的编译时间。
【讨论】:
如果您使用JSX 和babel,则必须在每个文件中导入React,因为babel-preset-react 会将您的JSX 代码转换为React.createElement() 调用,所以这段代码
const Foo = () => <h1>Test</h1>;
将会
var Foo = function Foo() {
return React.createElement(
"h1",
null,
"Test"
);
};
演示:Babel REPL
这就是为什么React 应该可以在适当的范围内访问的原因,并且一种方法是在文件中导入 React。
【讨论】:
babel 在转译时不导入 React 而我们应该手动进行?!!!
在nodejs 中,每个文件都是一个模块,它有自己的变量范围。当您将变量导入文件(例如React)时,您将此变量添加到模块范围,而不是全局范围。
如果是webpack,您可以使用providePlugin 轻松将React 变量设为全局变量:
new webpack.ProvidePlugin({
React: 'react' // ReactJS module name in node_modules folder
})
之后,您可以跳过在所有模块中导入 React 变量。 Webpack 会在需要的地方自行完成。
【讨论】:
nodejs也有global对象要说。