0

I have a test application that essentially gives a set of questions and shows one question after another when you press the next button. Each time the stack of questions becomes one less. I have an issue with state and the state-consuming component rendering in unexpected ways... I am using the useReducer hook and useContext but for the provided code I am just going to post the reducer as I feel like that is the main problem. When I press the button that dispatches to the "NEXT_QUESTION" action it works the FIRST TIME and the component re-renders with a new question, but any time after that the component ONLY re-renders by pressing the next button twice. Why do i have to press the next button two times to update my state? I can tell that the state is in fact updating as expected but I am not sure why it takes two button presses any time after the first one. here is my reducer... the console log is coming up every time. The deck is the array of questions

const deck=shuffler(deckFinal);

type State = {
    deck:QuestionType[],
    question:QuestionType,
    score:number,
}

type Action={
    type:'NEXT_QUESTION', 
    payload:string
}

export const questionReducer=(state: State, action: Action)=>{
    switch(action.type){
    case 'NEXT_QUESTION':
        console.log('next')
        const newState={     
                deck:state.deck.filter(item=>item.id!==action.payload),   
                question:state.deck[state.deck.length-1],
                score:70
        }
        return newState;
      
    }
    switch(action.type){
    case 'RESET_TEST':
        //add shuffler function here
        return action.payload
    }
}
Robert O'Toole
  • 197
  • 1
  • 11
  • Should the new `question` be the last element of the filtered deck? Not the old deck state? – windowsill Mar 16 '22 at 04:38
  • ah. i was thinking that the state.deck is technically the new filtered deck. that makes a lot of sense.... How exactly would I take off from the new state deck array rather than the old one? I can't reference it with newstate.deck inside of the newstate object. – Robert O'Toole Mar 16 '22 at 14:06
  • Maybe I can take it off the action.payload? sending in the old deck state... let me see! – Robert O'Toole Mar 16 '22 at 14:08
  • i tried sending in the deck through the dispatch making it available on the action.payload and that didn't work either. i guess that is still Just sending in the new filtered deck state case 'NEXT_QUESTION': const newState={ deck:state.deck.filter(item=>item.id!==action.payload.id), question:action.payload.deck[action.payload.deck.length-1], score:70 } return newState; } – Robert O'Toole Mar 16 '22 at 14:27
  • You have the statement that evaluates your new state right there, just have to use it. `const updated = state.deck.filter(item=>item.id!==action.payload); return { deck: updated, question: updated[updated.length - 1] }` – windowsill Mar 16 '22 at 16:36
  • wow yeah I am being foolish today! It is working perfectly now! THANK YOU! Been doing web dev for almost 3 years and still forget basic state stuff like this when i return to it! been working way too much with gatsby lately and just making websites lol.... thanks again! – Robert O'Toole Mar 17 '22 at 02:54

0 Answers0