最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - HOC import TypeError: Object(...) is not a function - Stack Overflow

programmeradmin4浏览0评论

I just tried to use a simple HOC with react. Here is the function :

import React from "react"

const withOptions = (WrappedComponent) => {

  return class extends React.Component {

    render() {
      return <WrappedComponent { ...this.props } />
    }
  }

}

export default withOptions

The problem seems to be in the way i export/import it.

Imported and used in a simple way, it works :

import withOptions from "./Options"
...

class BilanClimatique extends React.Component{
  ...
}
const StyledBilanClimatique = withStyles(styles)(BilanClimatique)
export default withOptions(StyledBilanClimatique)

But if i use an intermediate file like index.js

import withOptions from "./Options"

export {
  withOptions
}

And import it in my ponent like that

import {
  withOptions
} from "./index"

Here is what i get

Can someone help me understand this ?

EDIT :

I found that the ponent that is using the HOC is imported from the same file as the HOC :

import withOptions from "./Options"
import BilanClimatique from "./BilanClimatique"

export {
  withOptions,
  BilanClimatique
}

And that causes the problem, but I don't understand why... Here is a sandbox with the problem

I just tried to use a simple HOC with react. Here is the function :

import React from "react"

const withOptions = (WrappedComponent) => {

  return class extends React.Component {

    render() {
      return <WrappedComponent { ...this.props } />
    }
  }

}

export default withOptions

The problem seems to be in the way i export/import it.

Imported and used in a simple way, it works :

import withOptions from "./Options"
...

class BilanClimatique extends React.Component{
  ...
}
const StyledBilanClimatique = withStyles(styles)(BilanClimatique)
export default withOptions(StyledBilanClimatique)

But if i use an intermediate file like index.js

import withOptions from "./Options"

export {
  withOptions
}

And import it in my ponent like that

import {
  withOptions
} from "./index"

Here is what i get

Can someone help me understand this ?

EDIT :

I found that the ponent that is using the HOC is imported from the same file as the HOC :

import withOptions from "./Options"
import BilanClimatique from "./BilanClimatique"

export {
  withOptions,
  BilanClimatique
}

And that causes the problem, but I don't understand why... Here is a sandbox with the problem https://codesandbox.io/s/r074735yvo

Share Improve this question edited Aug 1, 2018 at 9:47 Jayffe asked Aug 1, 2018 at 6:03 JayffeJayffe 1,27910 silver badges13 bronze badges 4
  • I can't seem to replicate it. codesandbox.io/s/wq7xnmmx5w Could there be something else missing when you trimmed your code for SO? – dubes Commented Aug 1, 2018 at 9:05
  • I found the problem and kind of replicate the error: the ponent which is using withOptions hoc is also imported from index codesandbox.io/s/r074735yvo ... But i don't understand why this is a problem... – Jayffe Commented Aug 1, 2018 at 9:44
  • Thanks for replicating it. I will dig a bit. – dubes Commented Aug 1, 2018 at 9:52
  • Thanks for the question, I learnt a lot about modules while digging around. Hope my answer is clear, else let me know and I will try to elaborate further. – dubes Commented Aug 1, 2018 at 11:12
Add a ment  | 

2 Answers 2

Reset to default 12

This seems to be a problem with hoisting of 'exports'. From what I can see, the imports get hoisted, but I could not see anything similar for exports.

The flow which causes problem (codesandbox):

App.js:

import { BilanClimatique } from "./ponents/index";

./ponents/index.js:

// just using the "re-export" shortcut
export { default as BilanClimatique } from "./BilanClimatique";
export { default as withOptions } from "./Options";

./ponents/BilanClimatique.js:

import { withOptions } from "./index";

./ponents/Options.js:

const withOptions = WrappedComponent => {
  return ... //snipped code

export default withOptions;

When App.js asks index.js for BilanClimatique, it in turn asks the same index.js for withOptions. But since exports don't seem to be hoisted, index.js has not yet made withOptions available.

How to solve:

  1. Ordered exports:

in ./ponents/index.js, change the order of exports as per your dependency:

// just using the "re-export" shortcut
export { default as withOptions } from "./Options";
export { default as BilanClimatique } from "./BilanClimatique";

I would not remend it. It is very fragile.

  1. Use index.js to only expose to outside your namespace. Inside your namespace, rely on explicit imports.

i.e. in ./ponents/BilanClimatique.js:

import withOptions from "./Options";
  1. If you have a very large codebase, use multiple index.js for exporting your "contracts". Take a look at the codebases of various library authors, I think that is the strategy they take.

I would personally remend #2 over #3 unless you run into problems with #2.

. doesn't look as a great import path. Try to import from 'index' file.

import {
  Logo,
  withOptions
} from "./index"
发布评论

评论列表(0)

  1. 暂无评论