3

我是第一次玩 React,我想我真的很喜欢它。到目前为止,我已经实现了(大部分)棋盘游戏围棋,但我遇到了一些奇怪的事情,我不知道如何以惯用的 React 方式处理。基本上,我有一个模型——棋盘游戏——实现为它自己的类Board。它只公开它的构造函数、方法play(i,j)pass. 它处理所有游戏逻辑并适当地更新自己的内部状态。它没有引用与视图/组件相关的任何内容。我有一个名为BoardView的 React 组件,它维护对Board. 我还有一个名为AlertView在适当的时候显示有关游戏状态(非法移动等)的消息。

现在一切正常,我喜欢Board类和它的视图之间的关注点分离。但是,我让我的Board班级将其更改传达给视图的方式很不寻常,而且我觉得它与其他 React 代码不一致。基本上,我滥用jQuery 的事件系统来允许我触发任意事件,例如["update", "atari", "suicide"]. 在这个方案中,组件有一个 onClick 监听器,它会调用Board.play0 到 Board 实例上的许多事件。组件侦听"update"事件并调用this.setState,这将强制它重新render()- 将视图置于正确描述游戏的状态。AlertView侦听同一板实例上的 和 事件并类似地"atari"调用"suicide"this.setState, 这触发另一个render().

我应该删掉 jQuery 事件吗?如果是这样,最好的方法是什么?

所有代码都可以在此处获得,您可以在此处使用该应用程序。

编辑:为了后代,这个问题是在提交3f600c时提出的。

4

2 回答 2

2

我不确定这是否是惯用的 React,但从 React 教程中,onSubmit处理程序作为props.

在您的情况下,这意味着将onPlay处理程序从传递BoardViewBoardIntersection如下:

var BoardView = React.createClass({
  getInitialState: function() {
    return {"board": this.props.board}
  },
  playHandler: function(i, j) {
    this.props.board.play(i, j)
  },
  render: function() {
    ...
    intersections.push(BoardIntersection({
      color: this.state.board.board[i][j],
      row: i,
      col: j,
      onPlay: this.playHandler
    }));
    ...
  }
})

并将根据需要BoardIntersection调用onPlay

var BoardIntersection = React.createClass({
  handleClick: function() {
    this.props.onPlay(this.props.row, this.props.col);
  },
})
于 2013-12-31T03:14:49.150 回答
2

tungd 的评论为我指明了正确的方向,但我决定回答我自己的问题以获得更完整的答案。

我最终删除了在模型上触发的所有自定义事件。我发现 React 文档中的以下片段特别有用:

一种常见的模式是创建几个仅渲染数据的无状态组件,并在层次结构中在它们之上有一个有状态组件,通过 props 将其状态传递给其子级。有状态组件封装了所有的交互逻辑,而无状态组件则以声明的方式处理数据。

我没有在模型上触发诸如“atari”和“suicide”之类的事件,而是在模型上设置布尔属性,in_atari并且attempted_suicide. 现在,我的应用程序中只有一个“父”组件具有状态。它通过声明性道具呈现所有子组件。这AlertView是一个这样的子组件,其render方法现在检查新的布尔标志以呈现适当的文本。主父组件将处理程序传递给其更新组件状态的子组件(并随后强制重新render)。

在相关的提交中,我将父组件命名为 ContainerView。

于 2014-01-03T22:21:20.370 回答