首页 > 解决方案 > 当程序终止时,第一个减速器如何获取第二个减速器的值?

问题描述

我有 2 个减速器:winnerReducergameLockedReducer. console节目中的最后 2 行从 中gameLockedReducer获取值 ( X wins!) winnerReducer。它工作正常,直到前面提到的最后两行。

我的意思是,他们显然都处于两种不同的初始状态,这怎么可能发生?

如果需要更多信息,请告诉我。

这是 中的输出console

gameLockedReducer.js:8 [gameLockedReducer] ==> undefined
gameLockedReducer.js:8 [gameLockedReducer] ==> undefined
gameLockedReducer.js:8 [gameLockedReducer] ==> undefined
Board.js:31 this.gameState.totalMoves ==> 1
gameLockedReducer.js:8 [gameLockedReducer] ==> true
gameLockedReducer.js:8 [gameLockedReducer] ==> false
Board.js:31 this.gameState.totalMoves ==> 2
Board.js:31 this.gameState.totalMoves ==> 3
gameLockedReducer.js:8 [gameLockedReducer] ==> true
gameLockedReducer.js:8 [gameLockedReducer] ==> false
Board.js:31 this.gameState.totalMoves ==> 4
Board.js:31 this.gameState.totalMoves ==> 5
gameLockedReducer.js:8 [gameLockedReducer] ==> true
gameLockedReducer.js:8 [gameLockedReducer] ==> false
Board.js:31 this.gameState.totalMoves ==> 6
Board.js:78 6
Board.js:31 this.gameState.totalMoves ==> 7
winnerReducer.js:10 [winnerReducer] => X wins!
gameLockedReducer.js:8 [gameLockedReducer] ==> X wins!

这里是

import React, { Component } from 'react';
import './Board.css';
import { connect } from 'react-redux';
import * as actionTypes from '../../store/actions/actions';

class Board extends Component {
    constructor(props) {
        super(props);
        this.gameState = {
            turn: 'X',
            gameLocked: false,
            gameEnded: false,
            board: Array(9).fill(''),
            totalMoves: 0
        }
    }

    clicked(box) {
        if(this.gameState.gameEnded || this.props.gameLockedValue) {
            return;
        }

        if(this.gameState.board[box.dataset.square] === '') {
            this.gameState.board[box.dataset.square] = this.gameState.turn;
            box.innerText = this.gameState.turn;

            this.gameState.turn = this.gameState.turn === 'X' ? 'O' : 'X';
            this.gameState.totalMoves++;
        }

        console.log("this.gameState.totalMoves ==> " + this.gameState.totalMoves);

        var result = this.checkWinner();

        switch(result) {
            case 'X':
                this.gameState.gameEnded = true;
                this.props.winnerValueRedux("X wins!");
                break;
            case 'O':
                this.gameState.gameEnded = true;
                this.props.winnerValueRedux("O wins!");
                break;
            case 'draw':
                this.gameState.gameEnded = true;
                this.props.winnerValueRedux("Match is a draw");
                break;
            default:
                break;
        }

        // console.log("result ==> " + result);

        if(this.gameState.turn === 'O' && !this.gameState.gameEnded) {
            this.props.gameLockedValueRedux(true);
            // this.gameState.gameLocked = true;
            setTimeout(() => {
                do {
                    var random = Math.floor(Math.random() * 9);
                } while(this.gameState.board[random] !== '');
                this.props.gameLockedValueRedux(false);
                // console.log("reached here");
                this.clicked(document.querySelectorAll('.square')[random]);
            }, 3000)
        }
    }

    render() {
        return(
            <div id="game">
                <div id="state">{this.props.winnerValue} {this.props.gameLockedValue}</div>

                <div id="head">
                    Tic Tac Toe
                </div>

                <div id="board" onClick={(e) => this.clicked(e.target)}>
                    <div className="square" data-square="0"></div>
                    <div className="square" data-square="1"></div>
                    <div className="square" data-square="2"></div>
                    <div className="square" data-square="3"></div>
                    <div className="square" data-square="4"></div>
                    <div className="square" data-square="5"></div>
                    <div className="square" data-square="6"></div>
                    <div className="square" data-square="7"></div>
                    <div className="square" data-square="8"></div>
                </div>
            </div>
        );
    }
}

const mapStateToProps = state => {
    return {
        winnerValue: state.winnerValue.winnerValue,
        gameLockedValue: state.gameLockedValue.gameLockedValue
    };
};

const mapDispatchToProps = dispatch => {
    return {
        winnerValueRedux: (value) => dispatch({type: actionTypes.WINNER_VALUE, value}),
        gameLockedValueRedux: (value) => dispatch({type: actionTypes.GAME_LOCKED_VALUE, value})
    };
}


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

这是winnerReducer

import * as actionTypes from '../actions/actions';

const initialState = {
    winnerValue: ""
};

const winnerReducer = (state = initialState, action) => {
    switch(action.type) {
        case actionTypes.WINNER_VALUE:
            console.log("[winnerReducer] => " + action.value);
            return{
                ...state,
                winnerValue: action.value
            };
        default:
            return state;
    }
}

export default winnerReducer;

这是gameLockedReducer

import * as actionTypes from '../actions/actions';

const initialState = {
    gameLockedValue: false
};

const gameLockedReducer = (state = initialState, action) => {
    console.log("[gameLockedReducer] ==> " + action.value);
    switch(action) {

        case actionTypes.GAME_LOCKED_VALUE:

            return {
                ...state,
                gameLockedValue: true
            };
        default:
            return state;
    }
};

export default gameLockedReducer;

标签: javascriptreactjsdebuggingreduxreact-redux

解决方案


这里的问题在于 gameLockedReducer 中的 console.log。默认情况下,所有操作都传递给reducer。根据 actionType,您可以修改状态。在 gameLockedReducer 的情况下,控制台日志会被打印,因为它也接收到调度,但它实际上并没有改变状态,因为在 reducer 中没有满足任何 switch 情况。如果您将相同的控制台日志放在案例 actionTypes.GAME_LOCKED_VALUE 中,您应该会获得预期的正确日志记录行为。希望这可以帮助。


推荐阅读