redux dispatch多次触发

时间:2018-04-09 14:02:07

标签: redux react-redux redux-thunk

我在Redux中经历了以下不需要的行为(React / Redux + redux-thunk):我触发了一个事件(click),它会触发一个动作并将一些额外的数据作为数组中的对象发送。当我第一次点击数组中的一个对象(结果1:一个新对象)时,我会点击一次 - 那很好。

但现在发生了不必要的事情:

当我第二次点击调用新的附加数据时,操作将调度两次 - 第一次调用以前称为状态的数据(结果1) - 其次是新调用的状态数据(结果2:2)包含新数据的相同对象)。现在有三个对象在状态。

当我再次点击第三次调用新数据时,操作首先调度三次,结果1调度结果2,第三次调度再次调用新数据(结果3:三次相同)包含新数据的对象)。现在有6个对象在状态。

......等等......

我的期望:操作应该始终触发一次,并且reducer应该相应地添加新的数据对象,导致对象的数量总是等于点击量。

以下是一些代码:

行动:

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});
        });
    }
}

减速器:

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;
}

组件:

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);

我在哪里做或期待错?非常感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

您在每次getData来电时都会向套接字注册额外的事件处理程序。相反,您应该只在初始化时注册一个处理程序,而在emit中只注册getData

答案 1 :(得分:1)

就我而言,我使用的是redux-saga,即使动作只触发一次,我的saga中间件也会触发多次。我改变了我的传奇效果:

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

对此:

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

这并不完全是问题的答案,但是由于我也是由于类似的问题而找到此问题的,因此我希望它能对某人有所帮助。