我有以下模块结构:
/components
├── Button.js
├── Checkbox.js
├── index.js
├── DateSelect
├── DateSelect.js
└── index.js
使用/components/DateSelect/index.js
:
import DateSelect from './DateSelect';
export default DateSelect;
/components/index.js
:
import DateSelect from './DateSelect';
import Button from './Button';
import Checkbox from './Checkbox';
export {
DateSelect,
Button,
Checkbox,
};
/components/DateSelect/DateSelect.js
:
import { Checkbox } from '../';
// ...code
// I want to do this!
const MyCustomCheckbox = props => <Checkbox style={someStyle} />;
// ...code
class DateSelect extends React.Component {
// code
}
export default DateSelect;
现在,我想访问上面代码中的Checkbox
,在文件的顶级范围内,但我得到undefined
。但是,如果我在render
的{{1}}方法中访问此变量,则会按预期工作。
我不完全确定为什么会这样,或者我如何解决这个问题(我可以做DateSelect
,但我不想改变使用{的模式{1}}目录的文件),我也想知道究竟发生了什么。有什么想法吗?
答案 0 :(得分:1)
您的问题是您对/components/index.js
中的导出存在循环依赖关系。
当您的构建工具首次构建应用程序时,它会执行以下操作...
app.js
开始,从DateSelect
components/index.js
转到声明其导出的components/index.js
// SPOILER: This guy is your problem. We'll call him the douche.
export {
DateSelect,
Button,
Checkbox,
};
要声明的冲洗,需要从components/DateSelect.js
,components/Button.js
和components/Checkbox.js
DateSelect
,就会被告知从CheckBox
components/index.js
components/index.js
中的冲洗,所以它会在冲洗中寻找CheckBox
(它'圈回'),但CheckBox
尚未声明components/CheckBox.js
但是,它返回undefined
这是时间问题。在我们尝试导入之后,只需点击几下就可以定义CheckBox
,但是对于您的构建来说,点击几下就太晚了。
您可以通过立即记录CheckBox
并在导入语句后几毫秒来显示...
// /components/DateSelect/DateSelect.js:
import { Checkbox } from '../';
console.log(CheckBox); // undefined
setTimeout(() => console.log(CheckBox), 4) // function CheckBox(_ref) { ...
因此,当您尝试声明MyCustomCheckbox
时,CheckBox
未定义。
在调用了DateSelect
的render方法时,已声明CheckBox
。相对而言,这比构建过程晚了。
这种问题没有100%安全的解决方案,因为它取决于您的应用程序结构整体。通常最好避免绕回同一模块
避免冲洗
您可以通过直接从components/CheckBox.js
导入或者将索引模块方法更深一层并创建一个小的CheckBox模块来避免回到冲洗... ...
/components
/CheckBox
CheckBox.js
index.js
...然后import {CheckBox} from '/components/Checkbox'