【问题标题】:React global component反应全局组件
【发布时间】:2018-12-02 08:53:40
【问题描述】:

我来自 vue.js 背景,最近才开始研究 react。

我有一个组件:PageContent.jsx,我希望使用它而不需要经常导入它以便能够在渲染函数 (JSX) 中使用它。

在 vue 中,可以使用以下方式对组件进行全球化:

Vue.component(componentName, componentObject)

react 有类似的吗?

【问题讨论】:

    标签: javascript reactjs components create-react-app


    【解决方案1】:

    嗯,React 中没有任何类型的“全局”组件。每个组件都必须作为道具导入或传递。如果您想避免向每个文件添加导入,您有几个选择:

    1) 创建一个 Higher Order Component 来呈现 PageContent 和包装的组件。

    import PageContent from './PageContent';
    
    const withPageContent = WrappedComponent => {
      return class extends React.Component {
        render () {
          return (
            <PageContent>
              <WrappedComponent />
            </PageContent>
          )
        }
      }
    };
    
    export default withPageContent;
    
    // Usage
    
    import withPageContent from './withPageContent';
    
    class MyComponent extends React.Component {
      render () {
        return (
          <div>
            I'm wrapped in PageContent!
          </div>
        )
      }
    }
    
    export default withPageContent(MyComponent);
    

    2) 将PageContent 作为道具传递给组件:

    import PageContent from './PageContent';
    
    export default class App extends React.Component {
      render() {
        return (
          <React.Fragment>
            <Child1 content={PageContent} />
            <Child2 content={PageContent} />
          </React.Fragment>
        )
      }
    }
    
    // Usage
    
    export default class Child1 extends React.Component {
      render () {
        const PageContent = this.props.content;
        return (
          <PageContent>
            I'm wrapped in PageContent!
          </PageContent>
        )
      }
    }
    
    export default class Child2 extends React.Component {
      render () {
        const PageContent = this.props.content;
        return (
          <PageContent>
            I'm wrapped in PageContent!
          </PageContent>
        )
      }
    }
    

    【讨论】:

    • 感谢您的示例,尽管我真的在寻找一些东西来减少每个组件所需的导入量。如果我想与 react 合作,似乎我必须忍受这种情况
    • 是的,您仍然需要导入一些东西,但是您可以采取一些技巧来简化它。您可以使用webpack resolve 使您的导入路径更小并删除文件扩展名。您还可以创建一个导出多个组件的文件,然后您可以在一行中导入多个组件,如下所示:import { Button, Input, Icon } from 'utils/inputs';
    【解决方案2】:

    我非常同意Chase 的回答。 不过,如果您需要其他方法,您可以使用context api。您可以在 App 根目录或其他嵌套组件树中声明您希望轻松访问的组件集合。

    这里有一个useContext 钩子的例子,但钩子不是必须的。结构是标准的create-react-app结构。

    我们想要全局访问的组件 - src/deep/Header.js

    function Header() {
      return (
        <h1>
          I am a global component
        </h1>
      );
    }
    
    export default Header;
    

    上下文创建 - src/global-components-context.js

    import React from 'react';
    
    const MyContext = React.createContext(null);
    
    export default MyContext;
    

    全局组件的分组 - src/global-components.js

    import Header from './deep/Header';
    
    const contextValue = {
      Header,
    };
    
    export default contextValue;
    

    应用初始化文件 - src/index.js

    import React from 'react';
    import ReactDOM from 'react-dom';
    import App from './App';
    import MyContext from './global-components-context';
    import contextValue from './global-component';
    
    ReactDOM.render(
      <MyContext.Provider value={contextValue}>
        <App />
      </MyContext.Provider>,
      document.getElementById('root')
    );
    

    使用组件而不导入它 - src/App.js:

    import { useContext } from 'react';
    import globalComponent from './global-components-context';
    
    function App() {
      const Context = useContext(globalComponent);
      return (
        <div className="App">
          <Context.Header />
        </div>
      );
    }
    
    export default App;
    

    我认为这是您可以在 react 中拥有的最全球化的组件。请注意,您仍然需要在要使用全局组件的任何位置导入上下文。

    另外一项免责声明是,全局组件非常难以测试并且通常难以推理。我相信这就是为什么 react 没有标准解决方案的原因。

    希望我能帮上忙

    【讨论】:

      猜你喜欢
      • 2014-12-04
      • 2021-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      • 1970-01-01
      相关资源
      最近更新 更多