2017-07-15 84 views
0

我在渲染父级时遇到了React JS渲染子级的一些问题。 这里我试图实现“游戏人生”(Freecodecamp类的一个项目)。 我被困在这种情况下。我点击一个死细胞,它变得活着(蓝色)。然后,假设我想清除网格,即使所有单元格都死掉,但它不起作用。看起来,即使重新渲染父母也不会重新渲染孩子。React JS渲染父级不再渲染子级

有什么想法?

var board = []; 
 
var width = 80; 
 
var length = 50; 
 
var cells = width * length; 
 
var states = ["alive", "dead"]; 
 

 

 

 
class BoardGrid extends React.Component { 
 
    constructor(props) { 
 
    super(props); 
 
    //this.initBoardArray = this.initBoardArray.bind(this); 
 
    
 
    } 
 

 
    render() { 
 
    //this.initBoardArray(); 
 
    
 
    let boardDOM = this.props.board.map(function(cell) { 
 
     return <BoardGridCell status={cell.status} id={cell.id} />; 
 
    }); 
 

 
    return (
 
     <div id="game-grid"> 
 
     {boardDOM} 
 
     </div> 
 
    ); 
 
    } 
 
} 
 

 
class BoardGridCell extends React.Component { 
 
    render() { 
 
    return (
 
     <div 
 
     id={this.props.id} 
 
     className={`cell ${this.props.status}`} 
 
     data-status={this.props.status} 
 
     /> 
 
    ); 
 
    } 
 
} 
 

 
function initBoard() { 
 
    for (let cellIndex = 0; cellIndex < cells; cellIndex++) { 
 
     let cell = { id: cellIndex, status: "dead" }; 
 
     board[cellIndex] = cell; 
 
    } 
 
} 
 

 
function drawBoard() { 
 
    ReactDOM.render(
 
    <BoardGrid board={board} />, 
 
    document.getElementById("game-grid-wrapper") 
 
); 
 
} 
 

 
function clearBoard() { 
 
    for (let cellIndex = 0; cellIndex < cells; cellIndex++) { 
 
     let cell = { id: cellIndex, status: "dead" }; 
 
     board[cellIndex] = cell; 
 
    } 
 
} 
 

 
$("#game-grid-wrapper").on("click", ".cell", function() { 
 
    let currentState = $(this).attr("data-status"); 
 
    let currentStateIndex = states.indexOf(currentState); 
 
    let newState = states[(currentStateIndex + 1) % 2]; 
 
    $(this).attr("class", `cell ${newState}`); 
 
    $(this).attr("data-status", newState); 
 
}); 
 

 
$("#stop").on("click", function() { 
 
    alert("clearing"); 
 
    clearBoard(); 
 
    drawBoard(); 
 
}); 
 

 

 
initBoard(); 
 
drawBoard();
html, 
 
body { 
 
    height: 100%; 
 
    text-align: center; 
 
    font-family: 'Open Sans', sans-serif; 
 
} 
 

 
h1, 
 
h2 { 
 
    font-family: 'Press Start 2P', cursive; 
 
} 
 

 
.button { 
 
    width: 100px; 
 
    border: 1px solid #555; 
 
    padding: 5px; 
 
    margin: 5px; 
 
    cursor: pointer; 
 
    border-radius: 4px; 
 
} 
 

 
.button:hover { 
 
    opacity: 0.9; 
 
} 
 

 
#main { 
 
    margin: 10px; 
 
} 
 

 
#game-grid { 
 
    background-color: #000; 
 
    display: flex; 
 
    flex-wrap: wrap; 
 
    align-content: flex-start; 
 
    width: 800px; 
 
    height: 500px; 
 
    overflow: hidden; 
 
} 
 

 
#game-grid .cell { 
 
    border: 1px solid #767676; 
 
    width: 10px; 
 
    height: 10px; 
 
    color: #fff; 
 
    font-size: 9px; 
 
    box-sizing: border-box; 
 
} 
 

 
.alive { 
 
    background-color: #2185d0; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="main"> 
 
<div id="game-actions"> 
 
     <div id="start" class="button"><i class="fa fa-play"></i> Start</div> 
 
     <div id="pause" class="button"><i class="fa fa-pause"></i> Pause</div> 
 
     <div id="stop" class="button"><i class="fa fa-stop"></i> Stop</div> 
 
     </div> 
 
    <div id='game-grid-wrapper'></div> 
 
</div>

回答

0

你不应该使用jQuery与一起反应,如果你没有到。都操纵DOM,但基于不同的信息,这可能会使他们以意想不到的方式干扰。

对于您的董事会州,您应该use the state of your BoardGrid component。在渲染时,在构造函数中初始化您的状态,并在每个单元格中初始化您的状态add an onClick() callback

单击单元格时,调用板组件给出的回调函数,并将其传递给它。使用该ID在BoardGrid组件中使用setState()来更新电路板状态。

如果您遇到任何问题,我可以稍后添加一些示例代码。