redux dispatch fires multiple times

守給你的承諾、 提交于 2020-01-03 18:38:27

问题


I'm experiencing following unwanted behaviour in Redux (React/ Redux + redux-thunk): I'm triggering an event (click) wich lets an action fire and dispatch some additional data as objects in an array. When I'm clicking the first time the action dispatches once with one object in the array (result 1: one new object) - and that's fine.

But now the unwanted thing happens:

When I'm clicking the second time calling for new additional data the action dispatches twice - first time with the formerly called data in state (result 1) - secondly with the newly called data in state (result 2: two identical objects containing the new data). Having three objects in state now.

When I'm clicking the third time again calling for new data the action dispatches three times first with result 1 secondly with result 2 and the third time with the again-newly called data in state (result 3: three identical objects containing the new data). Having six objects in state now.

...and so on...

My expectation: The action should always fire once and the reducer should add the new data-object once accordingly resulting in that the amount of objects is always equal the the amount clicks.

Here is some code:

The action:

export function getData(idData) {
    return function (dispatch, getState) {
        dispatch({type: "FETCHING_DATA"});
        const socket = getState().socket.socket;
        socket.emit("requestData", idData);
        socket.on("responseData", function(newData){
            console.log("TRIGGER");
            dispatch({type: "GET_DATA", payload: newData});
        });
    }
}

The reducer:

export function priceMonitorReducers(
    state={
        data: [],
        isFetchingData: false,
    }, action) {
    switch (action.type) {
        case "FETCHING_DATA":
            return {...state, isFetchingData: true};
            break;
        case "GET_DATA":
            return {...state,
                data: [...state.data, action.payload],
                isFetchingData: false };
            break;
    }
    return state;
}

The component:

onGetData = (idData) => {
    this.props.getData(idData);
};

function mapStateToProps(state) {
    return {
        data: state.data,
        ...
    }
}

function mapDispatchToProps(dispatch) {
    return bindActionCreators({
        getData: getData
        ...
    }, dispatch);
}

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

Where am I doing or expecting wrong? Your help is much appreciated!


回答1:


You're registering an extra event handler to the socket on each getData call. Instead, you should register just one handler on initialization and only emit in getData.




回答2:


In my case I was using redux-saga, and my saga middleware was firing many times, even though the action only fired once. I changed my saga effect from this:

export default function* watchLogin() {
    while(true) {
        yield takeEvery(LOGIN, serverCreateInitialUser);  
    }
} 

to this:

export default function* watchLogin() {
    yield takeLatest(LOGIN, serverCreateInitialUser);  
}

This is not exactly an answer to the question, but since I found this question due to my similar problem, I am hoping it helps someone.



来源:https://stackoverflow.com/questions/49734848/redux-dispatch-fires-multiple-times

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!