为什么React在提升状态的同时运行缓慢?

时间:2019-05-12 04:46:29

标签: javascript reactjs

我正在制作一个游戏,其中一个制作迷宫,然后将其导出到数据库供其他人尝试。我正在制作一个非常大的网格(800 x 800),并将正方形变成黑色onMouseOver,以指示迷宫的墙壁。一段时间以来,它似乎运行良好,但是在某种程度上,它开始滞后onMouseOver,有点使游戏停滞不前。我不确定是否可以使div的颜色改变得足够快以使其起作用。

在我将Square组件的id移到Maze组件的状态以准备将其发送到后端之前,它似乎工作正常。

这是代码框:https://codesandbox.io/s/github/reedmacdonald/mazeProject


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>
    )
    }
}

很抱歉,我在其中放置了太多代码(如果您对事情的进展感到困惑,我花了很多代码),我只是不知道为什么onMouseOver落后很多。

1 个答案:

答案 0 :(得分:2)

我看到并解决的一些问题。

  1. 不需要每次都创建6400大小的阵列,因为您只需要迭代6400次。只需在组件外部创建一次,然后通过作用域查找即可使用它。
  2. maze不在任何地方进行渲染。因此,您可以将其作为Maze保留在this.maze实例上。调用setState会不必要地重新触发整个React生命周期。
  3. 您始终在switchColor处理程序中调用onMouseOver。与父级中的setState配合使用时,这非常昂贵。特别是因为该事件经常触发。因此,我已将对父对象的调用移至componentDidUpdate中,并根据调用的父对象编写了一些条件(prevState.colorToChange !== this.state.colorToChange)。您应该更改此条件以适合您的需求。

Codesandbox是here。这些只是我能想到的一些优化,并且该应用程序似乎响应良好。另外请记住,您不应该modify state directly

我通过在每个方块上使用refs进行了实验。我没有时间做一个完整的例子,但是这个想法就在那里。 link