Firebase + React Reducers seemingly getting mixed

2019-07-30 16:14发布

问题:

I've run into an odd issue, where my redux store seems to be returning a duplicate of a different value? (Still learning terms so sorry if I mixed them up!)

I have 2 states. Users, and Added. I want to show to lists, one using the data from each one of them. currently, fetchUsers works fine, but fetchAdded shows Users for an unknown reason so both lists show the same data.

If I switch fetchUsers to use refAdded then it shows Added, so now it only shows the added array in both lists. I figured that means the actual calls are working cause it can get the data from Firebase, but I don't know why this would happen.

FetchUsers which gets a list of users from firebase looks like this:

export function fetchUsers() {
    return (dispatch) => {
        refUsers.on('value', snapshot => {
            dispatch({
                type: 'FETCH_USER', 
                payload: snapshot.val()
            });
        });
    }
}

FetchAdded looks like this:

export function fetchAdded() {
    return (dispatch) => {
        refAdded.on('value', snapshot => {
            dispatch({
                type: 'FETCH_ADDED', 
                payload: snapshot.val()
            });
        });
    }
}

The reducers look like this:

export default function(state = [], action) {
    switch (action.type) {
        case 'FETCH_USER':
            return [action.payload];

        case 'ADDED_USER':
            return [action.payload, ...state];

        case 'MOVE_USER':
            const newState = [...state];
            newState.splice(action.payload.index, 1);
            return newState;

        case 'MOVE_ITEM':
            return [action.payload.user, ...state];

        default:
            return state
    }
}

and fetch Added is:

export default function(state = [], action) {
    switch (action.type) {
        case 'FETCH_ADDED':
            return [action.payload];

        case 'MOVE_ITEM':
            const newState = [...state];
            newState.splice(action.payload.index, 1);
            return newState;

        case 'MOVE_USER':
            return [action.payload.user, ...state]

        default:
            return state
    }
}

I combine them both here:

const rootReducer = combineReducers({
    users: UserReducer,
    added: AddedReducer
});

and my firebase client exporting looks like this:

firebase.initializeApp(config);

export const refUsers = firebase.database().ref("users")
export const refAdded = firebase.database().ref("added")
export const auth = firebase.auth
export const provider = new firebase.auth.GoogleAuthProvider();

In my actual page where I display the 2 lists, this is what I have:

function mapStateToProps(state) {
  return {
    users: state.users,
    added: state.added
  };
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators({ addUser, moveUser, moveItem, fetchUsers, fetchAdded }, dispatch);
}