【问题标题】:In React Native, how can I access methods of one component from another component?在 React Native 中,如何从另一个组件访问一个组件的方法?
【发布时间】:2015-08-13 20:45:30
【问题描述】:

我正在尝试从不同的组件访问 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);

【问题讨论】:

    标签: react-native


    【解决方案1】:

    这样的事情应该可以工作:

    '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);
    

    【讨论】:

    • 我不知道为什么那个人没有把这个作为正确答案,但是......谢谢老兄!哈哈哈你帮了我的模态!
    【解决方案2】:

    我认为将组件存储在 state 中不是一个好主意。状态应该真正用于组件的数据而不是子组件。上面 Dave 的解决方案是一个很好的方法,但它可以做得更好,因为它将模态状态移动到应用程序(这对于分离关注点不是很好)。如果 modal 可以保持自己的状态并知道它是否可见,那就太好了。然后 openModal() 和 closeModal() 可以根据需要做一些额外的事情(而不是以某种方式对 ShowModal 可见性的变化做出反应)。您还可以避免那些额外的 _openModal 和 _closeModal 样板文件。

    我认为最好使用 refs。 Refs 是引用其他组件的标准方式。有关 refs https://facebook.github.io/react/docs/more-about-refs.html 的更多详细信息,请参阅此处。您可以将 refs 用作字符串并通过该字符串引用组件,但这有点难看,因为引入了与 react 的组件方法相矛盾的全局名称。但是您也可以使用回调作为 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>
        )
      },
    });
    

    这里发生了什么 - 有问题的视图有回调 ref,它将 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 函数。

    【讨论】:

    • 这真的很酷,我绝对没有使用足够的回调函数!我将在我的回答中对此表示赞同。 :)
    猜你喜欢
    • 1970-01-01
    • 2017-12-09
    • 1970-01-01
    • 2023-03-04
    • 1970-01-01
    • 2019-05-10
    • 1970-01-01
    • 1970-01-01
    • 2016-11-09
    相关资源
    最近更新 更多