Reputation: 3
I'm refactoring a React application to use hooks and have found some success, but I think I am incorrectly dispatching actions (using useReducer) within my application. I've discovered that the state doesn't change immediately when using hooks, and it's causing my application to behave differently than it's class-based counterpart. Here's a piece of my code that dispatches state in which I used console.logs to see if the state has changed or not. In both instances where state.gameOver is logged to the console, it's false, as well as state.userIsWrong. I've attached their actions my reducer as well. Thank you for the help in advance!
const wrongAnswer = () => {
dispatch(toggleGameOver());
console.log(`game over1 ` + state.gameOver)
console.log('wrong answer')
sounds["wrong"].play();
//a delay is used to so that the header will return back to "Click me to begin game" or the current level of the game
//and to return the background to normal
setTimeout(() => {
dispatch(toggleGameOver());
console.log(`game over2` + state.gameOver)
dispatch(turnOnUserIsWrong());
},500)
}
turnOnUserIsWrong action from action.js
export const turnOnUserIsWrong = () => ({
type: 'TURN_ON_USER_IS_WRONG'
})
reducer.js
export default (state, action) => {
switch (action.type) {
case 'SET_ACTIVE_STYLE':
return {
...state,
activeStyle: action.style
}
case 'UPDATE_LAST_COLOR':
return {
...state,
lastColor: action.color
}
case 'UPDATE_USER_PATTERN':
return {
...state,
userPattern: [...state.userPattern, action.id]
}
case 'UPDATE_GAME_PATTERN':
return {
...state,
gamePattern: [...action.newGamePattern]
}
case 'TOGGLE_PRESSED':
console.log(action.color)
return {
...state,
pressed: action.color
}
case 'TURN_ON_READY_FOR_USER_INPUT':
console.log(`here`)
return {
...state,
readyForUserInput: true
}
case 'TURN_OFF_READY_FOR_USER_INPUT':
return {
...state,
readyForUserInput: false
}
case 'RESET_GAME':
return {
...state,
gamePattern: [],
userPattern: [],
lastColor: "",
level: 0,
gameStarted: false,
userIsWrong: false,
readyForUserInput: false,
activeStyle: '',
strictRestart: false
}
case 'UPDATE_LEVEL':
return {
...state,
level: state.level + action.level
}
case 'TURN_OFF_USER_IS_WRONG':
return{
...state,
userIsWrong: false
}
case 'TURN_ON_USER_IS_WRONG':
return{
...state,
userIsWrong: true
}
case 'TOGGLE_STRICT_MODE':
return {
...state,
strictMode: !state.strictMode
}
case 'TOGGLE_GAME_STARTED':
return {
...state,
gameStarted: !state.gameStarted
}
case 'TOGGLE_GAME_OVER':
return {
...state,
gameOver: !state.gameOver
}
case 'EMPTY_USER_PATTERN':
return {
...state,
userPattern: []
}
case 'SET_PLAYER_LEVEL':
return{
...state,
level: action.level
}
default:
return {
...state
};
}
}
Upvotes: 0
Views: 959
Reputation: 599
Not sure how you're retrieving your state using hooks, but I'm currently working on a React App using only hooks, I'll leave you an example that I hope it helps you:
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
//YOUR OTHER IMPORTS
const YOURCOMPONENTNAME = (props) => {
const gameOver = useSelector((state) => state.YOURREDUCERNAME.gameOver);
const dispatch = useDispatch();
const onToggleGameOver = () => dispatch(toggleGameOver());
const onTurnOnUserIsWrong = () => dispatch(turnOnUserIsWrong());
const wrongAnswer = () => {
onToggleGameOver();
console.log(`game over1 ` + gameOver)
console.log('wrong answer')
sounds["wrong"].play();
//a delay is used to so that the header will return back to "Click me to begin
//game" or the current level of the game and to return the background to normal
setTimeout(() => {
onToggleGameOver();
console.log(`game over2` + gameOver)
onTurnOnUserIsWrong();
},500)
}
// MORE CODE
}
export default YOURCOMPONENTNAME;
Not sure if this is of any help for you, hope it is. In case it´s not, I hope you find your answer!!
Upvotes: 1