2

在我的第一个文件 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

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

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

4

2 回答 2

0

我假设您想用一个按钮呈现一些页面,并在有人按下 FlatButton 时立即显示对话框。我还注意到您正在使用 material-ui,所以让我们开始吧。

在启动任何 React 项目时,考虑组件层次结构是个好主意。因为你使用的是material-ui,而Dialog组件的开启是通过传递props来控制的,所以最简单的方法是使用下面的方法。

简单案例

使用根组件 App(在 app.jsx 中),它会挂载一个按钮并挂载一个对话框,但对话框最初处于隐藏状态(Dialog 上的“open”属性默认为 false),因此尚未在视觉上显示(即使它已安装)。在这种情况下,您将希望按钮在按下按钮后立即将 Dialog 上的 open 属性设置为 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 组件的子组件或父组件)深处的某个地方时,我该如何组织它”,而是一个兄弟组件?

嗯,这对我来说有点味道(只是一个意见)。这不是一个反模式,但如果你能避免这种情况,我建议你这样做。即:为了您自己的方便和可维护性,尽量使自然交互的组件在组件层次结构中彼此靠近(就父子关系而言)。这样,您可以使用 props 轻松进行交流(请参阅 React 的相关信息。但这绝对不是绝对规则,有很多理由可以偏离它。

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

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

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

这两种方法都有严重的优点/缺点。第一种方法将您的 UI 渲染逻辑泄漏到您的商店中(无论如何这通常是不可避免的,但可以使用 Flux 之类的东西进行管理),第二种方法将其泄漏到组件层次结构中(难以维护)并且往往会产生紧密耦合(糟糕) .

于 2015-12-28T08:40:51.497 回答
0

当您调用 时Open._handleTouchTap,您正在尝试在类上调用该方法,就好像它是静态的一样Open。但是,此方法仅在Open组件被实例化后才可用。您必须将 a 附加ref到组件并通过 调用该方法this.refs.someOpenComponent._handleTouchTap()

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

此外,名称前带有下划线的方法通常表示“私有”方法,不应从不同的类调用。您可能需要考虑重命名此函数,以便更清楚地了解其用途。

于 2015-12-28T02:35:51.240 回答