发货行动后立即检查状态变量

时间:2017-01-24 03:35:29

标签: reactjs redux react-redux

我目前正在使用react-redux开发一个tic-tac-toe app。现在,在这里不会让人们分散无关代码,这是我面临的问题。

我的董事会是作为州的一部分存储的。当有人点击一个单元格时,我会调度一个应该更新电路板状态的动作。我一发出行动,就检查是否有胜利者。我的checkWinner()检查this.props.board(由reducer更新)似乎不是我检查获胜者时的最新信息。

play(ij) {
    let i = ij[0];
    let j = ij[1];
    this.props.play(i, j, this.props.currentPlayer); // dispatch action!

    let winner = this.checkWinner(); // need to check most updated state!
    if ( winner != '' ) {
        this.reset();
    }
}

你建议我在哪里检查获胜者?

[编辑]:添加一些代码以帮助调试。

Board.js

import React, { Component } from 'react';
import Cell from './Cell'
import styles from '../css/board.css'

import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import { createBoard, play, switchPlayer } from '../actions/index'

class Board extends Component {

    constructor(props) {
        super(props)    
        this.props.createBoard(this.props.rows, this.props.cols)
    }

    checkWinner() {
        // TODO: please add correct winner algo!
        // return this.state.board[0][0];
        return this.props.board && this.props.board[0][0];
    }

    drawBoard() {

        if ( !this.props.board )
            return <h1>Loading...</h1>;

        let board = [];
        for ( let i = 0 ; i < this.props.rows ; i++ ) {
            for ( let j = 0 ; j < this.props.cols ; j++ ) {
                var id = i + '' + j;
                board.push(
                    <Cell 
                        key={id}
                        id={id}
                        play={this.play.bind(this)}
                        value={this.props.board[i][j]} />
                );
            }
        }
        return board;
    }

    reset() {    
        this.props.createBoard(this.props.rows, this.props.cols);
    }

    play(ij) {
        let i = ij[0];
        let j = ij[1];
        this.props.play(i, j, this.props.currentPlayer);
    }

    componentWillReceiveProps() {
        let winner = this.checkWinner(); 
        if ( winner != '' ) {
            this.props.hasWinner(winner);
            this.reset();
        }
    }

    getClassName() {
        return styles.board
    }

    render() {
        return (
            <div className={this.getClassName()}>
                {this.drawBoard()}
            </div>
        )
    }

}

function mapStateToProps(state) {
    return {
        board: state.board,
        currentPlayer: state.currentPlayer
    }
}

function mapDispatchToProps(dispatch) {
    return bindActionCreators({
        createBoard: createBoard,
        play: play,
        switchPlayer: switchPlayer
    }, dispatch)
}

export default connect(mapStateToProps, mapDispatchToProps)(Board);

actions / index.js(播放方法)

export function play(row, col, val) {
    return {
        type: 'PLAY',
        payload: {
            row: row,
            col: col,
            val: val
        }
    };
}

reducer_board.js

function createBoard(rows, cols) {
    let board = new Array(rows);
    for ( var row = 0 ; row < rows ; row++ ) {
        board[row] = new Array(cols);
        board[row].fill('');
    };  

    return board;   
}

export default function reducer_board(state = 0, action) {

    if ( action.type === 'PLAY' ) {
        let board = state.map(function(row) {
            return row.slice();
        });
        board[action.payload.row][action.payload.col] = action.payload.val;
        return board;
    }

    if ( action.type === 'CREATE_BOARD' ) {
        return createBoard(action.payload.rows, action.payload.cols);
    }       

    return state;

}

1 个答案:

答案 0 :(得分:0)

您可以检查componentWillReceiveProps生命周期函数中的获胜者,因为只要在已安装的组件上更新道具,就会调用此方法。

 componentWillReceiveProps(nextProps) {
        let winner = this.checkWinner(nextProps); 
        if ( winner != '' ) {
            this.props.hasWinner(winner);
            this.reset();
        }
    }
    checkWinner(updProps) {
        // TODO: please add correct winner algo!

        return this.props.board && updProps.board[0][0];
    }

<强> DOCS