在父级的setState之后,子级组件未重新呈现(道具未分配给子级构造函数中的状态)... React似乎坏了(纯React)

时间:2019-06-18 23:08:06

标签: javascript reactjs

S,我已经查找了有关此问题的所有问题,遇到问题的人也遇到了将他们的孩子的道具设置为孩子状态的问题,而我却正确地在孩子的渲染图中称道具。

  • 我正在尝试使用样式化的按钮来制作John Conway在React中的生活游戏

  • 我在Game组件的状态中设置了一个二维布尔数组,该数组应该控制Square组件(无论它使用的是“ Alive”还是“ Dead” CSS类)

  • 每当游戏状态更新时,方形组件的状态都不会更新,我会设置console.log()来显示正在更新的内容

  • 父母的班级名称是游戏,孩子的班级名称是Square

  • 您可以忽略Game中的step()和countNeighbors()函数

  • 我怀疑问题与将大数组中的值传递给孩子的道具或在函数中生成孩子的道具有关

任何建议都值得赞赏

游戏组件:

class Game extends Component {
    constructor(props) {
        super(props);
        this.state = {
            vals: [],
            squares: [],
        }
        this.state.vals = this.genVals();
        this.state.squares = this.genSquares();
    }

    componentDidUpdate(prevProps, prevState, snapshot) {
        console.log('Game component updated');
        console.log(this.state.vals);
    }

    handleClick(i, j) { //yes this works, it was brought up from the depths of google so don't delete it before being sure it doesn't work
        this.setState({
            vals: {
                ...this.state.vals,
                [i]: {
                    ...this.state.vals[i],
                    [j]: !this.state.vals[i][j],
                }
            }
        });
        console.log(this.state.vals[i][j])
    }

    genVals() {
        let ret = [];
        for(let i = 0; i < 50; i++) {
            let row = []
            for(let j = 0; j < 50; j++) {
                row.push(false);
            }
            ret.push(row);
        }
        return ret;
    }

    genSquares() {
        let squares = [];
        for(let i = 0; i < 50; i++) {
            let row = [];
            for(let j = 0; j < 50; j++) {
                let square = <Square key={i + ',' + j} isAlive={this.state.vals[i][j]} handleClick={this.handleClick.bind(this, i, j)} 
                />; //pass what I want to control squares with down the props
                row.push(square);
            }
            squares.push(row);
        }
        return squares;
    }

    renderSquaresList() {
        let list = [];
        for(let i = 0; i < 50; i++) {
            list.push(<li key={i}>{this.state.squares[i]}</li>);
        }
        return <ul>{list}</ul>;
    }

    countNeighbors(i, j) { //many equivalent ways to approach this problem, I'm picking the simplest to read
        let count = 0;
        let squares = this.state.vals;

        //need to check boundaries since js throws a fit trying to read null/undefined objects instead of just implicitly delcaring falsy
        let topOk = (i > 0) ? true: false; //i is -y and j is x 
        let bottomOk = (i < 50) ? true: false;
        let leftOk = (j > 0) ? true: false;
        let rightOk = (j < 50) ? true: false;

        //count neighbors bottom to top (order is arbitrary)
        if(bottomOk && squares[i + 1][j])
            count++;
        if(bottomOk && rightOk && squares[i + 1][j + 1])
            count++;
        if(bottomOk && leftOk && squares[i + 1][j - 1])
            count++;
        if(rightOk && squares[i][j + 1])
            count++;
        if(leftOk && squares[i][j - 1])
            count++;
        if(topOk && squares[i - 1][j])
            count++;
        if(topOk && rightOk &&squares[i - 1][j + 1])
            count++;
        if(topOk && leftOk && squares[i - 1][j - 1])
            count++;

        return count;
    }

    step() {
        console.log(this);
        for(let i = 0; i < 50; i++) {
            for(let j = 0; j < 50; j++) {
                //console.log(this.squares[i][j]);
                let count = this.countNeighbors(i, j);
                //console.log(count);
                if(count == 3 || (count == 2 && this.state.vals[i][j])) { //I dont need the triple = because I know what types I'm dealing with
                    this.state.vals[i][j] = true;
                    this.forceUpdate(); //words cannot describe the stress of getting this code to work
                }
                else {
                    this.state.vals[i][j] = false;
                    this.forceUpdate();
                }
            }
        }
    }

    render() {
        return (
            <>
                {this.renderSquaresList()}
                <button onClick={this.step.bind(this)}>Step</button>
                <button onClick={this.handleClick.bind(this, 0, 0)}>Test</button>
            </>
        );
    }
}

平方分量(儿童道具):

class Square extends Component {
    constructor(props) {
        super(props);
    }

    componentDidUpdate(prevProps, prevState, snapshot) {
        console.log('Square component updated, is it alive? ' + this.props.isAlive);
    }

    render() {
        let className = "Dead";
        if(this.props.isAlive) {
            className = "Alive";
        }
        return (
            <button onClick={this.props.handleClick} className={className}></button>
        );
    }
}

CSS类:

.Alive {
    background-color: #e8e129;
    border: none;
    color: none;
    padding: 10px 10px;

}

.Dead {
    background-color: #061244;
    border: none;
    color: none;
    padding: 10px 10px;
}

ul {
    list-style-type: none;
    margin: 0;
    padding: 0;
}

li {
    line-height: 0;
}

0 个答案:

没有答案