【问题标题】:Why do you need to import React multiple times in parent and child components?为什么需要在父子组件中多次导入 React?
【发布时间】:2017-11-08 08:08:51
【问题描述】:

如果你有一个已经导入 React 的父组件文件,为什么它的任何渲染的子文件也需要导入 React?这是否只是一种安全措施,以防这些孩子被渲染到尚未导入 React 的其他地方?

【问题讨论】:

    标签: reactjs import webpack


    【解决方案1】:

    问题的根源在于依赖管理——作为作者,我如何在我的“事物”(应用程序/组件/模块)中描述和获取我需要的外部依赖项以使其完成工作?

    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 />
          );
        }
      };
    };
    

    总而言之,让每个“事物”导入自己的依赖项在某种程度上是一种“安全措施”。它使您可以安全地重构代码,而无需记住提供这些依赖项的认知开销。

    【讨论】:

      【解决方案2】:

      原因是为了避免不必要的编译一段你不必编译jsx的JavaScript代码。例如,你有一个文件需要添加一个函数,或者任何不需要编译 jsx 的函数,那么你不要把 import React from 'react' 放在那个文件。这将节省您的编译时间。

      【讨论】:

        【解决方案3】:

        如果您使用JSXbabel,则必须在每个文件中导入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 而我们应该手动进行?!!!
        • @dNitro 因为它只是一个转换代码的工具。如果你想在你的项目中拥有这样的功能,你总是可以为它创建一个 babel 插件或者使用已经存在的东西,比如npmjs.com/package/babel-plugin-react-require
        【解决方案4】:

        nodejs 中,每个文件都是一个模块,它有自己的变量范围。当您将变量导入文件(例如React)时,您将此变量添加到模块范围,而不是全局范围。

        如果是webpack,您可以使用providePlugin 轻松将React 变量设为全局变量:

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

        之后,您可以跳过在所有模块中导入 React 变量。 Webpack 会在需要的地方自行完成。

        【讨论】:

        • 谢谢!如果一个父组件文件同时导入了 React 和一个子组件,那么它们不是都在父组件的范围内吗?因此,孩子不会获得 React 的访问权限吗?
        • 但是nodejs也有global对象要说。
        • 所以它只是导出 module.exports 中的变量,而不是导入的其他文件,对吗?
        • 实际上,这并不能解释为什么在其范围内具有 React 的父级不与在其范围内的子级共享它。子组件位于父组件内部,然后将与子组件和 React 一起导出。在父组件被导出之前,它里面已经有 React 和一个子组件,那么为什么子组件不能直接访问父组件的 React 呢?
        • 导入的子组件和导入的 React 在同一个模块范围内,不是吗?
        猜你喜欢
        • 2011-09-09
        • 2018-01-03
        • 2013-09-18
        • 1970-01-01
        • 2021-01-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-14
        相关资源
        最近更新 更多