Do you want to request a feature or report a bug?
Bug
What is the current behavior?
React component imported from index.js file, which exports all components in one place returns undefined outside render function in container component. Path to components folder is resolved by webpack config resolve.modules option.
My file structure is:
├── components
│  ├── index.js
│  └── ui
│  ├── Checkbox.jsx
index.js file content:
/**
* UI components
*/
export Checkbox from './ui/Checkbox';
Container file component:
import React, { Component } from 'react';
import { Checkbox } from 'components'; // => undefined
import Checkbox from 'components/ui/Checkbox'; // => component function
/**
* Returns `undefined` when imported from index.js file in components folder
* Returns component function when imported directly from `components/ui` folder
*/
console.log(Checkbox);
/**
* Update: Returns component function in both cases
*/
setTimeout(() => {
console.log(Checkbox);
}, 100);
export default class Container {
render() {
/**
* Returns component function in both cases
*/
console.log(Checkbox);
return <div>test</div>;
}
}
What is the expected behavior?
Described in the code above.
Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
React - 15.6.1
OS - macOS 10.12.6
Browser - Google Chrome 61.0.3163.79
Fixed this weird bug by moving UI components section on top of the index.js file, I don't know why, but one broken component causes problem described above.
Your question is not about React, it is about ES6 modules. The difference between these two imports is that one of them is a named import but the other is a default import:
import { Checkbox } from 'components'; // => undefined
import Checkbox from 'components/ui/Checkbox'; // => component function
Since you are using a named export, only named import works in your case.
See this explanation: https://stackoverflow.com/a/36796281
Hope it helps!
@gaearon What's about the fact that console.log wrapper in something asynchronous like setTimeout or React.Component render function works in both cases?
I'm using both default and named, so Checkbox.jsx file exports component as default, but index.js file inside components folder exports Checkbox component and other not specified in the example components using additional export-from statements transpiled by transform-export-extensions. You did not understand the problem, one of my components exported in index.js file is broken somehow, and the only one thing that helped me was moving that broken component export to the bottom of the file.
Also, you can rewrite this for better understanding:
import { Checkbox } from './components/index.js'; // => undefined
import Checkbox from './components/ui/Checkbox.jsx'; // => component function
Can you provide a sample project?
@gaearon I can, but this does not make any sense, because the problem is specifically in my project. Most likely I made an error, but in a project with such a structure provided above everything should work flawlessly.
Update: I don't know how exactly ES Modules work under the hood, but probably the export order in the index.js file is important in this situation.
It is unfortunately hard to say anything conclusive without seeing the whole project. There are dozens of ways something can be misconfigured.
That's why I closed the issue, I can not publish project files here, so you can't really help me with my problem. If I'll find the error that causes this bug, I will definitely report it here.
You might also have circular dependencies which could explain why the imported value changes (apparently it does?)
In any case this is not a React bug.
I have the same problem. I will try to find circular dependencies in a project.
Update So I used Madge to find circular dependencies, found zero.
Solved by change order in index file exporting components
Most helpful comment
Your question is not about React, it is about ES6 modules. The difference between these two imports is that one of them is a named import but the other is a default import:
Since you are using a named export, only named import works in your case.
See this explanation: https://stackoverflow.com/a/36796281
Hope it helps!