Почему мой Redux вообще не меняет состояние? - PullRequest
0 голосов
/ 07 октября 2018

В попытке увидеть, работает ли Redux правильно, внутри checkWinner() я проверяю console.log("win value (is redux working?) ==> " + win); и вывод всегда:

win value (does redux work?) ==> [object Object]

Выход должен быть win value (does redux work?) ==> X.Мой редуктор написан неправильно?

Вот Board.js:

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.state = {
            winner: undefined,
        };

        this.gameState = {
            turn: 'X',
            gameLocked: false,
            gameEnded: false,
            board: Array(9).fill(''),
            totalMoves: 0
        }
    }

    clicked(box) {
        if(this.gameState.gameEnded || this.gameState.gameLocked) {
            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();

        // my attempt
        if(result === 'X') {
            this.gameState.gameEnded = true;
            let win = this.props.winnerValueRedux(this.state.winner);
            this.setState({
                winner: win,
                winnerLine: 'X wins'
            });
            console.log("win value (is redux working?) ==> " + win);
            console.log("X wins");
        // end of attempt

        } else if(result === 'O') {
            this.gameState.gameEnded = true;
            this.setState({
                winner: 'O',
                winnerLine: 'O wins'
            });
            console.log("O wins");
        } else if(result === "draw") {
            this.gameState.gameEnded = true;
            this.setState({
                winner: 'draw',
                winnerLine: 'match is a draw'
            });
        }
        console.log("result ==> " + result);

        if(this.gameState.turn === 'O' && !this.gameState.gameEnded) {
            this.gameState.gameLocked = true;

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

    render() {
        return(
            <div id="game">
                <div id="state">{this.state.winnerLine}</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
    };
};

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


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

Вот winnerReducer.js:

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

const initialState = {
    winnerValue: undefined
};

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

export default winnerReducer;

Ответы [ 2 ]

0 голосов
/ 07 октября 2018

После вызова этих кодов:

let win = this.props.winnerValueRedux(this.state.winner);
console.log("win value (is redux working?) ==> " + win);

Результат:

win value (does redux work?) ==> [object Object]

После использования JSON.stringify() я понял, что [object Object] равно {"type":"WINNER_VALUE"}, чтона самом деле отправленное действие , мы не увидели свойство value, присутствующее в этом действии, поскольку его значение было undefined .

И ваш вопрос:

Выходными данными должно быть значение win (работает ли приставка?) ==> X. Мой редуктор написан неправильно?

Все хорошо, ничего не неправильно.Неправильно то, что мы ожидали, что значение переменной win должно быть.

let win = this.props.winnerValueRedux(this.state.winner)

эквивалентно:

function winnerValueRedux(value){
   return dispatch({type: actionTypes.WINNER_VALUE, value})
}

let win = winnerValueRedux(value);

И это ключ, возвращаемое значениеметода dispatch(action) - это отправленное действие , которое является объектом .Вот почему вы получаете: win value (does redux work?) ==> [object Object]

Для получения дополнительной информации: рассылка (действие)


На данный момент мы понимаем, почему мы получили этот неожиданный результат.

Следующая часть проверяет, работает ли наше хранилище редуксов.

Я проверил и все заработало.Это демонстрационная версия: https://codesandbox.io/s/6xlv5rvqqk

Это коды, которые я использовал для отправки действий в хранилище с избыточностью:

if (result === "X") {
  this.gameState.gameEnded = true;
  this.props.winnerValueRedux("X");   //dispatch an action
} else if (result === "O") {
  this.gameState.gameEnded = true;
  this.props.winnerValueRedux("O");   //dispatch an action
} else if (result === "draw") {
  this.gameState.gameEnded = true;
  this.props.winnerValueRedux("draw");  //dispatch an action
}

Это коды, которые я использовал для получения состояния избыточности

<div id="state">{this.props.winnerValue}</div>   // get value from redux store

Я старался изо всех сил.Надеюсь, это поможет.

0 голосов
/ 07 октября 2018

Передача неверного или не обновленного (должно быть winner?) Аргумента для winnerValueRedux() - незначительная проблема.

Основная проблема - не выполнение "избыточного потока":

Диспетчер не выполняетне возвращает значения, он испускает сообщения / действия.Действия, обработанные редукторами, обновляют состояние в хранилище.Обновленное значение «возвращается» компоненту на mapStateToProps.

Поиск некоторых учебников / примеров.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...