我正在尝试从其他组件访问React Native组件的方法。它是通过道具传递的。不幸的是,似乎组件没有公开提供他们的方法。我怎样才能访问该方法?
看看下面的内容,你会看到InsideView有this.props.myModal,这是一个ShowMyModal组件。但是,它无法访问.openModal()方法。
'use strict';
var React = require('react-native');
var {
AppRegistry,
ActionSheetIOS,
StyleSheet,
Text,
View,
} = React;
var InsideView = React.createClass({
makeItOpen: function() {
debugger;
this.props.myModal.openModal();
},
render: function() {
return (
<View>
<Text onPress={() => this.makeItOpen()}>Click me!</Text>
</View>
);
}
});
var ShowMyModal = React.createClass({
getInitialState: function() {
return {
isModalOpen: false,
}
},
openModal() {
this.setState({isModalOpen: true});
},
closeModal() {
this.setState({isModalOpen: false});
},
render: function() {
return (
<Text>isModalOpen = {String(this.state.isModalOpen)}</Text>
);
}
});
var AwesomeProject = React.createClass({
getInitialState: function() {
return {
myModal: <ShowMyModal />,
}
},
render: function() {
return (
<View style={{padding: 30}}>
<InsideView myModal={this.state.myModal}/>
{this.state.myModal}
</View>
);
},
});
AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject);
答案 0 :(得分:4)
这样的事情应该有效:
'use strict';
var React = require('react-native');
var {
AppRegistry,
ActionSheetIOS,
StyleSheet,
Text,
TouchableOpacity,
View,
} = React;
var InsideView = React.createClass({
render: function() {
return (
<View>
<TouchableOpacity onPress={() => this.props.openModal()}><Text>Open modal!</Text></TouchableOpacity>
<TouchableOpacity onPress={() => this.props.closeModal()}><Text>Close modal!</Text></TouchableOpacity>
</View>
);
}
});
var ShowMyModal = React.createClass({
render: function() {
return (
<Text>isModalOpen = {String(this.props.isVisible)}</Text>
);
}
});
var SampleApp = React.createClass({
getInitialState: function() {
return {
isModalOpen: false
}
},
_openModal: function() {
this.setState({
isModalOpen: true
});
},
_closeModal() {
this.setState({
isModalOpen: false
});
},
render: function() {
return (
<View style={{padding: 30}}>
<InsideView openModal={this._openModal} closeModal={this._closeModal}/>
<ShowMyModal isVisible={this.state.isModalOpen}/>
</View>
);
},
});
AppRegistry.registerComponent('SampleApp', () => SampleApp);
答案 1 :(得分:4)
我不认为将组件存储在状态是个好主意。状态应该真正用于组件的数据而不是子组件。 Dave上面的解决方案是很好的方法,但它可以做得更好,因为它将模态的状态移动到应用程序(这对于分离问题不是很好)。如果模态可以保持它自己的状态并且知道它是否可见,这是很好的。然后openModal()和closeModal()可以根据需要做一些额外的事情(而不是以某种方式对ShowModal的可见性的变化做出反应)。你也可以避免那些额外的_openModal和_closeModal作为样板。
我认为最好使用refs。 Refs是引用其他组件的标准方式。有关refs https://facebook.github.io/react/docs/more-about-refs.html的详细信息,请参阅此处。您可以将refs用作字符串并通过该字符串引用组件,但它有点丑陋,因为引入的全局名称与反应的组件方法相矛盾。但您也可以使用回调作为refs将内部组件设置为字段。这是一个很好而简单的例子,就是react的文档:http://facebook.github.io/react-native/docs/direct-manipulation.html#forward-setnativeprops-to-a-child。我在这里复制它以防文档更新:
var MyButton = React.createClass({
setNativeProps(nativeProps) {
this._root.setNativeProps(nativeProps);
},
render() {
return (
<View ref={component => this._root = component} {...this.props}>
<Text>{this.props.label}</Text>
</View>
)
},
});
这里发生了什么 - 有问题的视图有回调引用,它将this._root设置为视图的后备组件。然后在组件中的任何其他位置,您可以使用this._root来引用它。
所以在你的情况下它可能如下所示(注意你需要那些匿名箭头函数而不是传递openModal / closeModal方法,因为在渲染_modal时尚未设置,你只能在以后使用它来引用它匿名方法)。
// ...
// InsideView render (same as in Dave's solution)
<View>
<TouchableOpacity onPress={() => this.props.openModal()}><Text>Open modal!</Text></TouchableOpacity>
<TouchableOpacity onPress={() => this.props.closeModal()}><Text>Close modal!</Text></TouchableOpacity>
</View>
// ...
// Sample App render ...
<View style={{padding: 30}}>
<InsideView openModal={ () => this._modal.openModal() } closeModal={ () => this._modal.closeModal() } />
<ShowMyModal ref={component => this._modal = component} />
</View>
然后你的初始ShowModal实现可以保持原样 - 使用它自己的状态和自己的openModal和showModal函数。