要求Alpha中的Beta工作正常,但要求Alpha中的Alpha返回空对象.尝试使用无效组件推送路由时,会抛出错误.
循环依赖关系可以在React Native中工作吗?如果没有,我该如何解决?
码
index.ios.js
'use strict'; var React = require('react-native'); var Alpha = require('./Alpha'); var { AppRegistry,NavigatorIOS,StyleSheet,Text,View,} = React; var ExampleProject = React.createClass({ render() { return ( <NavigatorIOS style={styles.container} initialRoute={{ component: Alpha,title: Alpha.title,wrapperStyle: styles.wrapper }} /> ); },}); var styles = StyleSheet.create({ container: { flex: 1,backgroundColor: 'white' },wrapper: { paddingTop: 64 } }); AppRegistry.registerComponent('ExampleProject',() => ExampleProject);
Alpha.js
'use strict'; var React = require('react-native'); var Beta = require('./Beta'); var { StyleSheet,TouchableHighlight,Text } = React; var Alpha = React.createClass({ statics: { title: 'Alpha' },goToBeta() { this.props.navigator.push({ component: Beta,title: Beta.title,wrapperStyle: styles.wrapper }); },render() { return ( <View> <TouchableHighlight style={styles.linkWrap} onPress={this.goToBeta}> <Text>Go to Beta</Text> </TouchableHighlight> </View> ); } }); var styles = StyleSheet.create({ linkWrap: { flex: 1,alignItems: 'center',padding: 30 },wrapper: { paddingTop: 64 } }); module.exports = Alpha;
Beta.js
'use strict'; var React = require('react-native'); var Alpha = require('./Alpha'); var { StyleSheet,Text } = React; var Beta = React.createClass({ statics: { title: 'Beta' },goToAlpha() { this.props.navigator.push({ component: Alpha,render() { return ( <View> <TouchableHighlight style={styles.linkWrap} onPress={this.goToAlpha}> <Text>Go to Alpha</Text> </TouchableHighlight> </View> ); } }); var styles = StyleSheet.create({ linkWrap: { flex: 1,wrapper: { paddingTop: 64 } }); module.exports = Beta;
幸运的是,JavaScript的导入和导出关键字通过使用作为间接级别的中间对象来延迟导入值来解决这个问题.一个具体的例子很容易理解.
具有进出口权
使用导出关键字从其各自的文件导出Alpha和Beta,并使用import关键字导入它们:
// Alpha.js import Beta from './Beta'; var Alpha = React.createClass({ /* ... */ }); export default Alpha;
这是因为在运行时,export关键字创建一个中间对象(相当于CommonJS中的module.exports),并以Alpha值分配一个名为default的属性.所以,以上导出语句在概念上类似于:
module.exports.default = Alpha;
导入Alpha的文件将获得对中间对象的引用,而不是Alpha本身,直到Alpha被直接使用.所以这里的代码实际上是懒惰地访问Alpha:
import Alpha from './Alpha'; var ExampleProject = React.createClass({ render() { return ( <NavigatorIOS style={styles.container} initialRoute={{ component: Alpha,wrapperStyle: styles.wrapper }} /> ); },});
懒惰的访问是通过运行与以下概念类似的代码实现的:
var AlphaExports = require('./Alpha'); var ExampleProject = React.createClass({ render() { return ( <NavigatorIOS style={styles.container} initialRoute={{ component: AlphaExports.default,title: AlphaExports.default.title,});
使用require()
使用CommonJS的要求,您还有其他选项:
方法1:懒惰装载
Alpha和Beta在用户从一个场景导航到下一个场景之前不需要彼此.为了使应用程序达到此状态,Alpha必须定义其导出(即,module.exports = Alpha必须运行为您的应用程序呈现Alpha组件).因此,当用户导航到显示Beta的场景时,Beta可以安全地要求Alpha,因此在这个时间点可以安全地测试Beta.
// Alpha.js var Alpha = React.createClass({ goToBeta() { // Lazily require Beta,waiting until Alpha has been initialized var Beta = require('./Beta'); this.props.navigator.push({ component: Beta,wrapperStyle: styles.wrapper }); } });
虽然在这种具体情况下不需要为Beta.js做同样的事情,因为Alpha是第一个加载的组件,但这可能是一个好主意,这样您的组件就以相同的方式处理依赖循环.
方法2:单个模块
另一个解决方案是将Alpha和Beta放在同一个JS文件中,以消除模块之间的循环.然后,您将从新的大型模块导出两个组件.
// AlphaBeta.js var Alpha = React.createClass({...}); var Beta = React.createClass({...}); exports.Alpha = Alpha; exports.Beta = Beta;
要求它:
// index.js var {Alpha,Beta} = require('./AlphaBeta');