我正在努力使用ReactJS创建Conway的生命游戏重制版。到目前为止,我只渲染了160个cols 120行的静态游戏区域,共计19,200个小div。
董事会好像很快就会出现问题,但由于某种原因,程序会挂起(在我将它放在一起的CodePen)一整分钟。当我查看Chrome开发工具(我还是非常新的)时,它似乎显示了一些渲染,然后如果编写完整的堆脚本则需要一分钟,然后再进行另一次快速渲染。脚本的键上给出的颜色与Listeners的颜色相同。
我不确定是什么可以挂起来,因为此时我的反应App中的所有内容都是静态的并且相对简单。
此设置是否有19,200个小div太多了?似乎不太可能。或者在分配大量事件监听器时,这个东西是否会冻结?我该如何解决这个问题?
请帮忙。我真的需要了解背景中发生的事情。 对任何有回答的人都有好的帮助,可以帮助我自己下次解决类似的问题。
/**
* @desc React Class Field renders game field
* @param {Array} state.fieldE - even iteration game board array
* @param {Array} state.fieldO - odd iteration game board array
* @param {Sting} props.config - default undefined. Name sets initial field config
* @param {Boolean} props.continue - Field continues to iterate while continue true
* @param {Number} props.speed - sets time between iterations
* @param {Number} props.zoom - sets board zoom in parent container
* @param {LifeGame~Callback} props.onReset - reset field and toggle parent reset state
* @param {LifeGame~Callback} props.incGen - reset field and toggle parent reset state
* @returns {HTML} playable game field
*/
class Field extends React.Component {
constructor(props) {
super(props)
this.onReset = this.onReset.bind(this);
this.state = ({
fieldE: undefined,
fieldO: undefined,
});
}
///Sets fieldE and fieldO in state to zero-filled arrays
onReset() {
const fieldE = [];
fieldE.length = 19200;
let i = 0;
while (i < 19200) fieldE[i] = 0, i++;
const fieldO = [...fieldE];
this.setState({
fieldE,
fieldO
});
}
componentWillMount() {
this.onReset();
}
render() {
console.log('props: ', this.props);
console.log('state: ', this.state);
//Converts appropriate field array to HTML for output
const evenGen = (this.props.generation % 2 === 0);
const fArr = evenGen ? [...this.state.fieldE] : [...this.state.fieldO];
let len = fArr.length;
let cols = Math.sqrt(4 / 3 * len);
let field = fArr.map((el, i) => {
if (i + 1 % cols === 0) {
return <span id = 'f'
className = 'c' > < /span>}
return <span className = 'c' > < /span>;
});
let outField = [],
i = 0,
j = 0; outField.length = cols;
//uses outField to separate field into rows encapsulated by divs
while (j < len) {
outField[i] = < div className = 'r' > {
field.slice(j, j + cols)
} < /div>;
j += cols;
i++;
}
return ( <
div class = 'game-field' > {
outField
} <
/div>
);
}
}
//Calls Field for render
class LifeGame extends React.Component {
constructor(props) {
super(props);
this.state = {
config: undefined,
isContinue: false,
speed: 1,
zoom: 0,
generation: 0,
}
}
render() {
return ( <
Field config = {
this.state.config
}
isContinue = {
this.state.continue
}
generation = {
this.state.generation
}
speed = {
this.state.speed
}
zoom = {
this.state.zoom
}
/>
);
}
}
ReactDOM.render( <
LifeGame / > ,
document.getElementById('root')
);
html,
body,
div,
span,
ul,
ol,
h1,
h2,
h3,
h4 {
margin: 0;
padding: 0;
}
.game-field {
display: flex;
flex-shrink: 1;
row-wrap: nowrap;
}
.c {
display: inline-block;
flex-shrink: 0;
height: 4px;
width: 4px;
border-left: 1px solid rgba(192, 192, 192, 0.4);
border-bottom: 1px solid rgba(192, 192, 192, 0.4);
background: black;
margin: 0;
padding: 0;
}
.r {
display: flex;
flex-direction: row;
flex-shrink: 1;
flex-grow: 0;
row-wrap: nowrap;
position: relative;
text-align: center;
background: rgba(255, 255, 150, 0.6);
}
<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>
<div id="root">
<!-- This div's content will be managed by React. -->
</div>
(编辑) 另外, 如果事实证明19,200个div太多了(即使它们快速渲染),其他人如何将游戏板与时间元素放在一起?我怎么能这样做?
看起来像React在渲染后执行querySelectorAll和CalculateNewProcessedItemsBySelector。这些似乎是Chrome DevTool的暗示,但如果是,我不知道该怎么做。
答案 0 :(得分:0)
我刚刚注意到几年前的这个问题从未有人回答过。我对这个原始问题的解决方案——以及大多数人第一次遇到他们试图添加太多 html 元素的项目的解决方案——是使用 html5 canvas。