Javascript 为什么在提升状态时反应运行缓慢?
我正在制作一个游戏,其中一个人制作一个迷宫,然后将该迷宫导出到数据库,供其他人尝试。我正在制作一个非常大的网格(800 x 800),并在MouseOver上将正方形变成黑色,以指示迷宫的墙壁。有一段时间,它似乎工作得很好,但在某种程度上,它开始在MouseOver上落后,有点扼杀了游戏。我不确定是否可以使Javascript 为什么在提升状态时反应运行缓慢?,javascript,reactjs,Javascript,Reactjs,我正在制作一个游戏,其中一个人制作一个迷宫,然后将该迷宫导出到数据库,供其他人尝试。我正在制作一个非常大的网格(800 x 800),并在MouseOver上将正方形变成黑色,以指示迷宫的墙壁。有一段时间,它似乎工作得很好,但在某种程度上,它开始在MouseOver上落后,有点扼杀了游戏。我不确定是否可以使divs的颜色变化足够快,以使其正常工作 在我将方形组件的id移动到迷宫组件的状态以准备将其发送到后端之前,它似乎工作正常 下面是代码沙盒: 类扩展组件{ 建造师(道具){ 超级(); 此.
div
s的颜色变化足够快,以使其正常工作
在我将方形组件的id移动到迷宫组件的状态以准备将其发送到后端之前,它似乎工作正常
下面是代码沙盒:
类扩展组件{
建造师(道具){
超级();
此.state={
按钮单击:“”,
buildShowing:'内联',
testShowing:'无',
测试:错误,
对,,
完成显示:'inline',
提交显示:'无',
迷宫:[],
名称:“”
}
}
changeToRed=()=>{
这是我的国家({
提交显示:'内联',
finishShowing:'无',
按钮勾选:“红色”,
测试:true})
}
名称此迷宫=(e)=>{
e、 预防默认值()
var nameValue=document.getElementById(“uniqueID”).value
这是我的国家({
名称:nameValue
})
警报(`name现在是${this.state.name}`)
}
handleSubmit=async(e)=>{
e、 预防默认值();
const mazeResponse=等待获取(“/maze”{
方法:“POST”,
凭据:“包括”,
正文:JSON.stringify(this.state),
标题:{
“内容类型”:“应用程序/json”
}
})
const parsedResponse=await mazeResponse.json();
console.log(parsedResponse)
}
pushValueUp=(砖)=>{
此.state.maze.push(砖块)
这是我的国家({
梅兹:这个。州。梅兹
})
}
render(){
const arrayOne=新数组(6400).fill('hello')
const theMaze=arrayOne.map((电影,i)=>{
返回(
)
})
返回(
完成迷宫
提交迷宫
{theMaze}
测试迷宫
建造迷宫
说出名字
)}
}
类Square扩展组件{
建造师(道具){
超级(道具);
此.state={
刀疤:这个,道具,刀疤,
颜色:'白色',
colorToChange:null,
变色:假,
点击:this.props.clicked
};
}
达恩斯=()=>{
这个.props.pushValueUp(这个.props.scar)
}
开关颜色=()=>{
(this.state.colorToChange==='black'和this.props.button=='red')&&this.hitWall()
这个
这是我的国家({
真的,
colorToChange:this.props.button})
}
render(){
返回(
)
}
}
很抱歉,我在里面放了这么多代码(我取出了大量代码,以防你弄不清楚代码放在哪里了),我只是不知道为什么MouseOver上的
滞后了这么多。我看到并解决了一些问题
不需要每次都创建6400大小的数组,因为您只需要迭代6400次。只需在组件外部创建一次,然后通过范围查找使用它
maze
不用于任何渲染位置。因此,您可以将其保留在Maze
实例上,就像this.Maze
一样。调用setState
将不必要地重新触发整个生命周期
您总是在onMouseOver
处理程序中调用switchColor
。当与父级中的setState
结合使用时,这相当昂贵。特别是因为该事件经常被触发。因此,我将对parent的调用移动到了componentdiddupdate
,并根据调用parent的条件编写了一些条件(prevState.colorToChange!==this.state.colorToChange
)。你应该改变这个条件以适应你的需要
代码沙盒是。这些只是我能想到的一些优化,而这个应用程序似乎反应良好。还要记住,你不应该
我通过在每个正方形上使用参考点进行实验。我没有时间做一个完整的例子,但想法就在那里 我看到并解决了一些问题
不需要每次都创建6400大小的数组,因为您只需要迭代6400次。只需在组件外部创建一次,然后通过范围查找使用它
maze
不用于任何渲染位置。因此,您可以将其保留在Maze
实例上,就像this.Maze
一样。调用setState
将不必要地重新触发整个生命周期
您总是在onMouseOver
处理程序中调用switchColor
。当与父级中的setState
结合使用时,这相当昂贵。特别是因为该事件经常被触发。因此,我将对parent的调用移动到了componentdiddupdate
,并根据调用parent的条件编写了一些条件(prevState.colorToChange!==this.state.colorToChange
)。你应该改变这个条件以适应你的需要
代码沙盒是。这些只是我能想到的一些优化,而这个应用程序似乎反应良好。还要记住,你不应该
我通过在每个正方形上使用参考点进行实验。我没有时间做一个完整的例子,但想法就在那里 你能创造一个新的世界吗?当我们看到事情发生时,修复它会更容易。@MaazSyedAdeeb在导航栏上单击“
class Maze extends Component{
constructor(props){
super();
this.state = {
buttonClicked:'',
buildShowing: 'inline',
testShowing: 'none',
testing: false,
clicked: true,
finishShowing:'inline',
submitShowing:'none',
maze:[],
name:''
}
}
changeToRed = () => {
this.setState({
submitShowing:'inline',
finishShowing: 'none',
buttonClicked:'red',
testing: true})
}
nameThisMaze = (e) => {
e.preventDefault()
var nameValue = document.getElementById("uniqueID").value
this.setState({
name: nameValue
})
alert(`name is now ${this.state.name}`)
}
handleSubmit = async (e) => {
e.preventDefault();
const mazeResponse = await fetch('/maze', {
method: 'POST',
credentials: 'include',
body: JSON.stringify(this.state),
headers:{
"Content-type" : 'application/json'
}
})
const parsedResponse = await mazeResponse.json();
console.log(parsedResponse)
}
pushValueUp = (brick) => {
this.state.maze.push(brick)
this.setState({
maze:this.state.maze
})
}
render(){
const arrayOne= new Array(6400).fill('hello')
const theMaze = arrayOne.map((movie, i) => {
return (
<Square pushValueUp = {this.pushValueUp} scar={i} clicked =
{this.state.clicked} key={i} name="brick" button=
{this.state.buttonClicked} color={this.state.colorToChangeMaze}
className= 'cell'/>
)
})
return (
<div onDoubleClick={this.changeToClicked}>
<div onMouseOver={(this.state.testing) ?
this.outOfBounds:undefined} className="outOfBounds"></div>
<div onMouseOver={(this.state.testing) ?
this.outOfBounds:undefined} className="outOfBoundsTwo"></div>
<div onMouseOver={(this.state.testing) ?
this.outOfBounds:undefined} className="outOfBoundsThree"></div>
<form onSubmit={this.handleSubmit}>
<button type="button" onClick={this.changeButtons}
className="finishMaze" style=
{{'display':this.state.finishShowing}}>Finish Maze</button>
<button type="submit" className="finishMaze"
style=``{{'display':this.state.submitShowing}}>Submit Maze</button>
<div className="grid">
{theMaze}
</div>
</form>
<button className="startEndButton" onClick={this.changeToRed} style={{'display':this.state.testShowing}}>Test Maze</button>
<button className="startEndButton" onClick={this.changeToBlack} style={{'display':this.state.buildShowing}}>Build Maze</button>
<form className="nameForm" onSubmit={this.nameThisMaze}>
<input id = "uniqueID" name = "mazeName" className="giveName" type="text" placeholder=" Name of Your maze"></input>
<button type="submit"> Give name</button>
</form>
</div>
)}
}
class Square extends Component{
constructor(props) {
super(props);
this.state = {
scar: this.props.scar,
color: 'white',
colorToChange:null,
changeColor: false,
clicked:this.props.clicked
};
}
darnThis = () =>{
this.props.pushValueUp(this.props.scar)
}
switchColor =()=>{
(this.state.colorToChange==='black' && this.props.button=== 'red')&& this.hitWall()
this.darnThis()
this.setState({
changeColor:true,
colorToChange:this.props.button})
}
render(){
return(
<div className="boxes" onMouseOver = {this.switchColor} style={{'height':'5px','width':'5px','backgroundColor':this.state.changeColor ? this.state.colorToChange : this.state.color,'margin':'0'}}>
</div>
)
}
}