React循环依赖项导入命名导出

时间:2018-04-11 06:13:47

标签: reactjs

我有2个容器,都导入一个名为PageHeader的组件,这是一个功能组件,并像这样导入/导出....

(这适用于我导入的任何组件,而不仅仅是PageHeader)

组件/ PageHeader / PageHeader.jsx

import React from 'react';
import PropTypes from 'prop-types';

import './PageHeader.sass';

const PageHeader = ({ title, description, image }) => (
  <div className="section is-paddingless is-hidden-touch">
    <div className="header header__desktop" style={{ backgroundImage: `url('${image}')` }}>
      <h3 className="is-size-3 has-text-weight-semibold">{title}</h3>
      <h5>{description}</h5>
    </div>
  </div>
);

PageHeader.propTypes = {
  title: PropTypes.string.isRequired,
  description: PropTypes.string.isRequired,
  image: PropTypes.string.isRequired,
};

export default PageHeader;

组件/ PageHeader / index.js

import PageHeader from './PageHeader';
export default PageHeader;

在我的组件文件夹的根目录中,我有....

组件/ index.js

......
export { default as PageHeader } from './PageHeader';
......

这允许我将组件导入到容器中......

import { DelayedComponent, Loading, Page, PageHeader, ClientList, RecentlyViewed, ClientFilter } from '../../components';

当我只有1个容器时,这个工作正常,我现在已经引入了第二个容器,这实际上是第二个页面。

我的容器如下......

容器/客户/ Clients.jsx

import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types';

import { DelayedComponent, Loading, Page, PageHeader, ClientList, RecentlyViewed, ClientFilter } from '../../components';

import headerImage from '../../assets/images/client-search-banner.jpg';

class Clients extends Component {
  state = { selector: 'ALL' };

  static propTypes = {
    fetchClientListAction: PropTypes.func.isRequired,
    selectClientAction: PropTypes.func.isRequired,
    isLoading: PropTypes.bool.isRequired,
    clients: PropTypes.array.isRequired,
  };

  componentDidMount() {
    this.props.fetchClientListAction();
  }

  onClientSelect = client => this.props.selectClientAction(client);

  onFilterTenantList = selector => this.setState({ selector });

  render() {
    const { isLoading, clients } = this.props;
    const { selector } = this.state;

    if (isLoading)
      return (
        <DelayedComponent>
          <Loading />
        </DelayedComponent>
      );

    return (
      <Fragment>
        <PageHeader
          title="Choose a client"
          description="Bacon ipsum dolor amet ribeye biltong tongue, pig brisket venison fatback pork bacon kielbasa burgdoggen salami strip steak."
          image={headerImage}
        />
        <Page>
          <Page.Columns>
            <Page.Column modifiers="is-paddingless">
              <ClientFilter clients={clients} selector={selector} filterByLetter={this.onFilterTenantList} />
            </Page.Column>
          </Page.Columns>
          <Page.Columns modifiers="is-multiline">
            <Page.Column modifiers="is-two-thirds">
              <ClientList clients={clients} selector={selector} onClientSelect={this.onClientSelect} />
            </Page.Column>
            <Page.Column modifiers="is-one-third">
              <RecentlyViewed />
            </Page.Column>
          </Page.Columns>
        </Page>
      </Fragment>
    );
  }
}

export default Clients;

容器/ EmployeeSearch / EmployeeSearch.jsx

import React, { Component } from 'react';
import PropTypes from 'prop-types';

import { PageHeader } from '../../components';

import headerImage from '../../assets/images/client-search-banner.jpg';

class EmployeeSearch extends Component {
  render() {
    return (
             <PageHeader
          title="Search"
          description="Bacon ipsum dolor amet ribeye biltong tongue, pig brisket venison fatback pork bacon kielbasa burgdoggen salami strip steak."
          image={headerImage}
        />
    );
  }
}

export default EmployeeSearch;

执行此操作会导致Webpack崩溃并出现以下错误...

/Users/xxxxx/Code/xxxxx/search-webapp/node_modules/toposort/index.js:29
      throw new Error('Cyclic dependency: '+JSON.stringify(node))
                                                 ^

TypeError: Converting circular structure to JSON
    at JSON.stringify (<anonymous>)
    at visit (/Users/xxxxx/Code/xxxxx/search-webapp/node_modules/toposort/index.js:29:50)
    at visit (/Users/xxxxx/Code/xxxxx/search-webapp/node_modules/toposort/index.js:47:9)
    at visit (/Users/xxxxx/Code/xxxxx/search-webapp/node_modules/toposort/index.js:47:9)
    at Function.toposort [as array] (/Users/xxxxx/Code/xxxxx/search-webapp/node_modules/toposort/index.js:22:22)
    at Object.module.exports.dependency (/Users/xxxxx/Code/xxxxx/search-webapp/node_modules/html-webpack-plugin/lib/chunksorter.js:50:35)
    at HtmlWebpackPlugin.sortChunks (/Users/xxxxx/Code/xxxxx/search-webapp/node_modules/html-webpack-plugin/index.js:364:35)
    at /Users/xxxxx/Code/xxxxx/search-webapp/node_modules/html-webpack-plugin/index.js:113:21
    at AsyncSeriesHook.eval [as callAsync] (eval at create (/Users/xxxxx/Code/xxxxx/search-webapp/node_modules/tapable/lib/HookCodeFactory.js:24:12), <anonymous>:7:1)
    at AsyncSeriesHook.lazyCompileHook [as _callAsync] (/Users/xxxxx/Code/xxxxx/search-webapp/node_modules/tapable/lib/Hook.js:35:21)
error An unexpected error occurred: "Command failed.

但是,如果我更改EmployeeSearch.jsx中的导入,那么它看起来像这样....

import PageHeader from '../../components/PageHeader';

有效。

我完全失去了,并希望得到一些关于为什么/如何发生以及如何在不添加组件的多个import语句的情况下解决这个问题的输入。

我的容器呈现如下....

import React from 'react';
import Loadable from 'react-loadable';
import { Switch, Route } from 'react-router-dom';

import Loading from './components/Loading';

const AsyncRoute = loader =>
  Loadable({
    loader,
    loading: Loading,
    delay: 300,
  });

const Clients = AsyncRoute(() => import(/* webpackChunkName: "clients" */ './containers/Clients'));
const EmployeeSearch = AsyncRoute(() => import(/* webpackChunkName: "employee-search" */ './containers/EmployeeSearch'));

const Routes = () => (
  <Switch>
    <Route exact path="/" component={Clients} />
    <Route path="/employee-search/:client" component={EmployeeSearch} />
  </Switch>
);

export default Routes;

1 个答案:

答案 0 :(得分:0)

事实证明我在我的组件index.js文件中包含了App。

我的路线包含在App中,因此这是我的循环依赖。