使用React-Redux的生命游戏

时间:2016-09-14 20:53:35

标签: javascript reactjs redux react-redux conways-game-of-life

目前我正在研究Building Game of Life in FCC,我认为这将是一个很好的项目来测试我对React-Redux的了解。

由于我是Redux的新手,因此我很难理解这个项目中的哑组件与智能组件是什么。

在我看来,这是我看到的:

注意:当我说"智能组件" vs" Dumb Component"我只是想成为一个"智能组件"它是一个容器,或与应用程序状态相关的东西,在这里作为一个" Dumb组件"简单地说,它的工作就是简单地呈现它所喂养的任何东西。

如果我的假设是正确的,那么我很难在单元格上正确设置应用程序状态。

这是我到目前为止所写的内容:

组件/ board.js

import React, { Component } from 'react';
import Cell from '../containers/cell'

export default class Board extends Component {
  constructor(props){
    super(props);
    this.state = {height: 18, width: 40}
    this.test = this.test.bind(this)
  }
  test(){
    console.log(this.state)
  }
  render(){
    let rows = [];
    for (var i = 0; i < this.state.height; i++){
      let rowID = `row${i}`
      let bin = []
      for (var idx = 0; idx < this.state.width; idx++){
        let cellID = `cell${i}-${idx}`
        bin.push(<Cell key={cellID} id={cellID}/>)
      }
      rows.push(<tr key={i} id={rowID}>{bin}</tr>)
    }
    return(
      <div className="container">
        <div className="row">
          <div className="col s12 board"></div>
            <table id="simple-board">
               <tbody>
                 {rows}
               </tbody>
             </table>
          </div>
      </div>
    )
  }
}

容器/ cell.js

import React, { Component } from 'react';

// import from '../actions/index';
// import { connect } from 'react-redux';
// import { bindActionCreators } from 'redux';


export default class Cell extends Component{
  constructor(props){
    super(props);
    this.state = {
      color: 'dead'
    };
    this.test = this.test.bind(this);
  }

  test(){
    this.state.color === 'dead' ? this.setState({color:'alive'}) : this.setState({color:'dead'})
  }

  render(){
    return (
      <td
        className={this.state.color}
        key={this.props.cellID}
        id={this.props.cellID}
        onClick={this.test}>
      </td>
    )
  }
}

// function mapDispatchToProps(dispatch){
//   return bindActionCreators({}, dispatch)
// }

// export default connect(null,mapDispatchToProps)()

我不确定此刻我该如何接近。起初我想过必须将所有单元格包装在一个数组中,这将是应用程序的状态,但我不确定如何继续这样做。

非常感谢任何回复

1 个答案:

答案 0 :(得分:2)

我建议您像这样制作层次结构。我将把组件层次结构表示为类似JSON的语法,以便您可以理解:

App (smart) {
  dispatchProps: {
    ...gameControlActions, // gets passed into GameControls
    onCellClick, // gets passed down to Board, and then to each Cell
  }
  stateProps: {
    cells: [{
      id: #
      status: 'dead', // or 'alive'
    }], // gets passed down to Board, to render cells
    ...generationData, // gets passed down to Generation
  }
}
  // Children of App
  GameControls (dumb) // start, clear, randomize
  Board (dumb)
    Cells (dumb)
  Generation (dumb)

渲染单元格时,您可以像这样渲染它们:

<Cell key={cellID} id={cellID} status={status} onClick={this.props.onCellClick} />

Cell组件中render函数看起来像这样,您现在可以摆脱state

render(){
  return (
    <td
      className={this.props.status}
      id={this.props.id}
      onClick={this.props.onClick.bind(null, this.props.id)}>
    </td>
  )
}

您的onCellClick行动将如下所示:

function onCellClick(cellId) {
  return {
    type: 'CELL_CLICK',
    payload: cellId,
  };
}

然后,您可以通过切换单元格数组中该单元格的status来处理reducer中的该操作(请记住返回cells的新副本)。此外,如果有必要,您可能需要延长Cell组件PureComponent,以便加快对帐流程或实施shouldComponentUpdate

如果这没有意义,或者如果您有疑问(我认为您会这样做),请告诉我。