Search code examples
javascriptnode.jsreact-nativereduxstore

a variable becomes undefined somewhere in a reducer but it works fine in another reducer, react native, Redux


I am programming my first react native app. In this app, a chatbot, dialogs are incremented using an int (say intToFollow) that keeps track of how many phrases have been shown and each phrase is shown after a specific action (usually ACTION1, sometimes ACTION2) has been sent. Everything works great until there.

Now when I try to implement another action doing something else but needing to manipulate said intToFollow, it tells me that my int is undefined or NaN, and I am very lost because to me my new reducer looks exactly like my other one who is still working perfectly. My question is: can a same state be manipulated by multiple reducers successively ? is there something big I am missing?

Edit explanation : dialogFr and Eng are arrays containing objects, hence the properties sometimes mentioned afterward (like .steps), and they are used selectively depending on the language the user selected. intToFollow's main role is to be the index of each array, and to change each time a certain button is pressed to the next object, or to whatever objects it lands on after being incremented with the value of .steps. That is the part that works with no problem. ACTION2 is meant to do the same thing with the small change that the incrementation of intToFollow is fixed (here 1) and I can't just use ACTION1 because of other reasons ! //end of edit

import { createStore } from "redux";
import { dialogFr } from "../ressources/dialogsFrance";
import { dialogEng } from "../ressources/dialogsEng";


const initialState = {
    isEnglish: true,
    intToFollow: 0,
    currentDialog: "a",
    condition: false,

}

function reducer(state = initialState, action) {
    let nextState

    switch (action.type) {

        case 'ACTION_1':
            const intToFollow = state.intToFollow;
            nextState = {
                ...state,
                intToFollow: intToFollow + dialogFr[intToFollow].steps,
                currentDialog: state.isEnglish ? dialogEng[intToFollow] : dialogFr[intToFollow],


            }
            return nextState || state

        case 'ACTION_2':

            const condition = state.condition;
            if (condition === true) {

                nextState = {
                    ...state,
                    intToFollow: intToFollow + 1,
                    currentDialog: state.isEnglish ? dialogEng[intToFollow] : dialogFr[intToFollow],
                }
                return nextState || state
            }

        default:
            return state
    }
}


const store = createStore(reducer, initialState)
export default store

My problem is that dialogEng[intToFollow] and dialogFr[intToFollow] are considered undefined in ACTION2 but works fine in ACTION1

Using console.log, I have found that intToFollow enters the second reducer as NaN, thus rendering dialog arrays Undefined. However, this store is the only place where inToFollow is defined and manipulated, so I am stuck looking at the same 10 lines of codes for hours... That's all I've got !


Solution

  • When action.type === ACTION_2, the code becomes this:

    import { createStore } from "redux";
    import { dialogFr } from "../ressources/dialogsFrance";
    import { dialogEng } from "../ressources/dialogsEng";
    
    
    const initialState = {
        isEnglish: true,
        intToFollow: 0,
        currentDialog: "a",
        condition: false,
    }
    
    function reducer(state = initialState, action) {
        let nextState
    
        switch (action.type) {
            case 'ACTION_2':
    
                const condition = state.condition;
                    if (condition === true) {
    
                    nextState = {
                        ...state,
                        intToFollow: intToFollow + 1,
                        currentDialog: state.isEnglish ? dialogEng[intToFollow] : dialogFr[intToFollow],
                    }
                    return nextState || state
                }
    
            default:
                return state
        }
    }
    

    Where is intToFollow declared?

    You only declared it inside your ACTION_1.

    You should either:

    1. declare it outside the switch
    2. declare it inside ACTION_2 as well
    3. or change the lines intToFollow: intToFollow + 1, and currentDialog: state.isEnglish ? dialogEng[intToFollow] : dialogFr[intToFollow] to intToFollow: state.intToFollow + 1, and currentDialog: state.isEnglish ? dialogEng[state.intToFollow] : dialogFr[state.intToFollow], respectively.