将方法从一个文件传递给另一个文件

时间:2015-12-28 02:26:25

标签: javascript reactjs material-ui

在我的第一个文件中说,open.jsx,我有:

    // Default Import Statements here

var open = React.createClass({

  render() {
    return (
      <div>
        <Dialog
          title="Test"
          ref="openDialog">
        </Dialog>
      </div>
    );
  },
  _handleTouchTap() {
    this.refs.openDialog.setState({open:true});
  }
});

module.exports = open;

在我的app.jsx文件中,我有:

const testComponent = React.createClass({
    render() {
    return (
          <FlatButton label="Test" onTouchTap={this._handleTouchTap}/>
    );
  },

  _handleTouchTap: function() {
    Open._handleTouchTap();
  }
});

module.exports = testComponent;

我目前得到的错误是: Uncaught TypeError: Open._handleTouchTap is not a function

有谁知道如何在文件之间传递反应方法?

我想在open.jsx's _handleTouchTap()按下按钮时调用app.jsx方法。

2 个答案:

答案 0 :(得分:0)

当您致电Open._handleTouchTap时,您试图在Open课程上调用该方法,就好像它是静态的一样。但是,只有在Open组件实例化后才能使用此方法。您必须将ref附加到组件,然后通过this.refs.someOpenComponent._handleTouchTap()调用该方法。

您可能希望提供更多代码,以便提供更好的示例。

此外,在名称前加下划线的方法通常表示“私有”方法,不应从其他类调用。您可能需要考虑重命名此功能,以便更清楚它的用途是什么。

答案 1 :(得分:0)

我假设你想用一个按钮渲染一些页面,并在有人按下FlatButton时立即显示对话框。我也注意到你正在使用material-ui,所以让我们继续使用它。

在启动任何React项目时,最好考虑一下组件层次结构。因为你正在使用material-ui并且Dialog组件的开放是通过传递道具来控制的,所以最简单的方法是使用以下方法。

简单案例

使用根组件App(在app.jsx中),它安装一个按钮并安装一个对话框,但该对话框最初处于隐藏状态(Dialog上的“open”prop默认为false)所以不能直观显示(即使它已安装)。在这种情况下,按下按钮后,您将需要按钮将Dialog上的open prop设置为true。

请注意我建议将大部分渲染内容分成单独的组件;为了便于说明,我们将所有内容保存在App.jsx中。

在这种情况下,您想要组织的方式如下:

// App.jsx (render + handle click function only)
render: function() {
  return (
      <div>
          <FlatButton label="Test" onTouchTap={this._handleTapTestButton}/>
          <Dialog
            title="Test"
            open={this.state.dialogOpen}>
            <div>My dialog contents</div>
          </Dialog>
      </div>
  );
},
_handleTapTestButton: function() {
  this.setState({dialogOpen: !this.state.dialogOpen}); // flip the state
}

请参阅?甚至不需要参考(这很好!)。现在,如果您的Dialog组件位置很好并且靠近FlatButton,这样可以正常工作。

更复杂的情况:Dialog远离FlatButton

您的下一个问题可能是“当Dialog组件嵌套在一个完全不同的组件(不是App.jsx组件的子组件或父组件”的深处)时,我该怎么组织这个问题,但是而不是兄弟姐妹?

嗯,这对我来说有点味道(只是一个意见)。这不是一个反模式,但如果你可以避免这种情况,我建议你这样做。即:为了您自己的方便和可维护性,尝试在组件层次结构中保持彼此自然交互的组件(就父子关系而言)。通过这种方式,你可以很容易地使用道具进行交流(参见React的info。这绝对不是绝对的规则,有很多理由偏离它。

让我们假设您有一个有效的案例,即不这样做,更糟糕的是:该组件是兄弟姐妹,而不是直接或间接的祖父母/父母/子女。

在这种情况下,您有两种选择:

  • 使用商店和相关事件(或任何其他传达状态的javascript代码)将状态更改传达给其他组件(即使用Flux,Redux或您喜欢的任何内容)。在这种情况下,单击该按钮时,您将触发另一个组件拾取的某个事件。此事件触发另一个组件的状态更改。警告:这很快就会变得无法管理,这也是像Flux和Redux这样的状态管理框架存在的原因之一。
  • OR,onTouchTap,让FlatButton调用一个从共享父组件传递下来的函数。然后,此函数翻转共享父组件的状态,并将此状态作为props传递给Dialog。即,当两个组件在某处共享祖父母时,您可以在祖父级别定义一个函数,并将该函数作为支撑向下传递给FlatButton。该函数的作用是更改祖父母的状态(dialogOpen)。然后,这个状态作为一个或多个组件向下传递到层次结构中,直到它最终到达Dialog,它将自动显示为prop将切换为true。

任何一种方法都有严重的优点/缺点。第一种方法将UI渲染逻辑泄漏到您的商店中(无论如何通常是不可避免的,但可以使用Flux之类的东西进行管理),第二种方法将其泄漏到组件层次结构中(对于可维护性而言很棘手)并且倾向于创建紧密耦合(yuck)