I'm currently trying out reactjs, trying to make a MVC based card game with it. I find that ReactJS is a very capable and good performing view library, but I have some troubles mapping it to a more traditional MVC pattern where the views listen to the models.

In the card game I have 2 rows of cards on the table, one of the current player and one of the opponent player. The cards of the current player are in the bottom row and they are selectable. In my GameView i render 2 child views, like this:

<SlotView key="slotview1" slot={this.state.otherPlayer.slot} selectable={false} /> <SlotView key="slotview2" slot={this.state.currentPlayer.slot} selectable={this.state.playing_cards} on_select={this.handlePlayCard}>

when the turn is over I swap the current player and the other player (in the game model) and notify the gameview via an event. The gameview's state is updated, and then it rerenders itself from the perspective of the other player.

This works fine, the cards of the other player show in the bottom row. But, the problem I am running into is that the SlotView (child view of the game view) also listens to its model (it updates itself when a card is played).

I bind the listeners in SlotView#ComponentDidMount and unbind them in SlotView#ComponentDidUnmount. However, the component is only mounted during the first render, and never unmounted and mounted again. Its property (slot) is being updated to the other player, but it still listens to events from the first player. Is there a way I can listen to property changes to bind/unbind event handlers? Or should I not listen to models at all in child components and replace the MVC model with a more push oriented model (but this seems to produce a lot of boilerplate code with nested views)? Should I unbind/rebind in the render method itself (but that seems wrong too)?

Curious to hear how other people do this....

有帮助吗?

解决方案

I overlooked an API call (componentWillReceiveProps). So in my SlotView I use the following logic to listen/stop listening to the slot model. Still curious to know if there are better patterns possible.

componentWillReceiveProps: function(nextProps) {
  if (nextProps.slot && nextProps.slot != this.props.slot) {
    this.props.slot.removeListener('change', this.slotListener);
    nextProps.slot.on("change",this.slotListener);
  }
},


slotListener : function (data) {
  this.setState({ selectedIndex: -1 })
},


componentDidMount: function () {
  var self = this;
  this.props.slot.on("change",this.slotListener)

},

componentWillUnmount: function () {
  this.props.slot.removeListener('change', this.slotListener);
},
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top