使用 React-Redux 的生命游戏
Game of Life using React-Redux
目前我正在研究 Building Game of Life in FCC,我认为这将是一个很好的项目来测试我在 React-Redux 方面的知识。
由于我是 Redux 的新手,我很难理解这个项目中什么是哑组件和智能组件。
在我看来,我是这样看的:
注意:当我说 "Smart Component" 与 "Dumb Component" 时,我的意思只是说 "Smart Component" 它是一个容器,或者与应用程序状态相关的东西,其中作为"Dumb Component" 只是意味着它的工作就是简单地渲染它正在被喂食的任何东西。
如果我的假设是正确的,那么我很难在单元格上正确设置应用程序状态。
这是我到目前为止所写的内容:
component/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>
)
}
}
container/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)()
我不确定此时我该如何处理。起初我想过必须将所有单元格包装在一个数组中,这将是应用程序的状态,但我不确定如何继续。
任何回复将不胜感激
我建议您按照这样的层次结构。我将把组件层次结构表示为类似 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
来处理缩减器中的该操作(请记住 return cells
的新副本)。此外,如有必要,您可能需要使 Cell
组件扩展 PureComponent
,以加快协调过程或实施 shouldComponentUpdate
.
如果这没有意义,或者您有任何疑问(我想您会的),请告诉我。
目前我正在研究 Building Game of Life in FCC,我认为这将是一个很好的项目来测试我在 React-Redux 方面的知识。
由于我是 Redux 的新手,我很难理解这个项目中什么是哑组件和智能组件。
在我看来,我是这样看的:
注意:当我说 "Smart Component" 与 "Dumb Component" 时,我的意思只是说 "Smart Component" 它是一个容器,或者与应用程序状态相关的东西,其中作为"Dumb Component" 只是意味着它的工作就是简单地渲染它正在被喂食的任何东西。
如果我的假设是正确的,那么我很难在单元格上正确设置应用程序状态。
这是我到目前为止所写的内容:
component/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>
)
}
}
container/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)()
我不确定此时我该如何处理。起初我想过必须将所有单元格包装在一个数组中,这将是应用程序的状态,但我不确定如何继续。
任何回复将不胜感激
我建议您按照这样的层次结构。我将把组件层次结构表示为类似 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
来处理缩减器中的该操作(请记住 return cells
的新副本)。此外,如有必要,您可能需要使 Cell
组件扩展 PureComponent
,以加快协调过程或实施 shouldComponentUpdate
.
如果这没有意义,或者您有任何疑问(我想您会的),请告诉我。