0

I have application (quiz-game) where user can click on button "New Game" and new game will start. I want to reset all my redux store when user is clicked on it. I have root reducer that combines all app reducers. And i want to reset them to initial state after clicking the button. I saw Dan Abramov answer (https://stackoverflow.com/a/35641992/11580012) and did the same, but nothing happens. I mean initial state doesn't set up.

Here some code bellow:

Component class

class GameMenu extends Component {
    constructor(props) {
        super(props);

        this.state = {
            modalIsOpen: false,
            modalMessage: '',
            modalType: undefined // 0 for new game, 1 for end game
        };

        this.openModal = this.openModal.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
        this.handleCancel = this.handleCancel.bind(this);
    }

    openModal (e) {
        this.setState({ modalIsOpen: true });
    }

    handleSubmit () {
        this.setState({ modalIsOpen: false });

        if(this.state.modalType === 0) {
            this.props.startNewGame();
            this.props.history.push('/');
        } else {
            this.props.endGame();
        }
    }

    handleCancel () {
        this.setState({ modalIsOpen: false });
    }

    render() {
        return (
            <div className="menu">
                <button onClick={this.openModal} id="newGameButton">New Game</button>
                <button>Leader Board</button>
                <button onClick={this.openModal} id="endGameButton">End Game</button>

                <Modal
                    isOpen={this.state.modalIsOpen}
                    onCancel={this.handleCancel}
                    onSubmit={this.handleSubmit}
                >
                    <p>{this.state.modalMessage}</p>
                </Modal>
            </div>
        )
    }
}

const mapStateToProps = state => {
    return {
        players: state.players,
        answeredQuestionsArray: state.questions.answeredQuestionsArray,
        topics: state.questions.topics,
    }
};

const mapDispatchToProps = {
    startNewGame,
    endGame
};

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

Root reducer:

import { questionsReducer } from "./questions/reducers";
import { playersReducer } from "./players/reducers";

import {START_NEW_GAME} from "./actions";
import {END_GAME} from "./actions";

const appReducer = combineReducers({
    questions: questionsReducer,
    players: playersReducer
});

const rootReducer = (state, action) => {
    if (action.type === START_NEW_GAME) {
        state = undefined;
    }
    return appReducer(state, action);
};

export default rootReducer;
const initialState = {
    answeredQuestionsArray: [],
    topics: []
};

export const questionsReducer = (state = initialState, action) => {
    switch (action.type) {
        case CHANGE_ANSWERED_QUESTIONS_ARRAY:
            return {
                ...state,
                answeredQuestionsArray: action.payload
            };
        case LOAD_TOPICS:
            return {
                ...state,
                topics: action.payload
            };
    }

    return state;
};
export const startNewGame = () => ({
    type: START_NEW_GAME
});

After this.props.history.push('/) state doesn't change to initial.

  • Can you show your `startNewGame`. Also the place where your configure your store ? – Panther May 10 '20 at 13:23
  • I'd suspect the history.push is the problem: a.) you're modifying a prop (not going through the store) if I understand it right; and b.) .push might not always be recognized as it's still the same array. A replacement like ```history = [...history, '/']``` probably could save you, but still, you're modifying a prop – Sebastian Rothbucher May 10 '20 at 13:33
  • Looks good. Are you using something like redux-presist ? May be state update is happening on '/` component ? – Panther May 10 '20 at 13:35
  • also, if you really have to set state to undefined, I'd check for undefined in the reducer, b/c you'll certainly have an issue when using ...undefined in the reducer – Sebastian Rothbucher May 10 '20 at 13:36
  • I don't use Redux-Presist. And state doesn't change without history.push also. – Дмитрий Каспорский May 10 '20 at 13:39
  • Could you please share the code for the `actions`? And verify that action with type `START_NEW_GAME` actually get called? and condition inside the `rootReducer` evaluated to `true` – MonteCristo May 10 '20 at 14:51
  • @ДмитрийКаспорский are you sure that you actually set the `this.state.modalType` to 0 because in the code you have provided you are not changing it state anywhere. – Slavian May 10 '20 at 15:04

2 Answers2

0

When you connect mapDispatchToProps to a component, you have to call dispatch inside otherwise your action is not dispatched. For example:

const mapDispatchToProps = dispatch => {
  return {
    // dispatching plain actions
    startNewGame: () => dispatch({ type: START_NEW_GAME })
}

It's handy to use Redux DevTools (chrome extension) to debug this kind of issue.

Yupeng Li
  • 136
  • 4
0

The problem was different. I wrote incorret logic in reducer. The reset way is correct. Thank you for help!