redux dispatch 多次触发

Posted

技术标签:

【中文标题】redux dispatch 多次触发【英文标题】:redux dispatch fires multiple times 【发布时间】:2018-09-18 23:08:53 【问题描述】:

我在 Redux(React/Redux + redux-thunk)中遇到了以下不良行为:我正在触发一个事件(点击),它允许一个动作触发并将一些额外的数据作为数组中的对象分派。当我第一次单击时,操作会在数组中使用一个对象分派一次(结果 1:一个新对象) - 这很好。

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

当我第二次单击调用新的附加数据时,操作会分派两次 - 第一次是之前调用的数据处于状态(结果 1) - 第二次是新调用的数据处于状态(结果 2:两个相同的对象包含新数据)。现在有三个处于状态的对象。

当我再次单击第三次调用新数据时,动作分派三次,首先是结果 1,第二次是结果 2,第三次是再次新调用的处于状态的数据(结果 3:三个相同的对象包含新数据)。现在有六个对象处于状态。

...等等...

我的期望:动作应该总是触发一次,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);

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

【问题讨论】:

你能分享你的组件的所有代码吗?我们需要查看点击处理程序以及它在组件中的调用位置。 谢谢马特。点击处理程序不是问题。我接受了一个解决了我的错误的答案。 【参考方案1】:

在我的例子中,我使用的是 redux-saga,我的 saga 中间件被触发了很多次,尽管动作只触发了一次。我从这个改变了我的传奇效果:

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

到这里:

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

这不完全是问题的答案,但由于我发现这个问题是由于我的类似问题,我希望它对某人有所帮助。

【讨论】:

【参考方案2】:

您在每次getData 调用时向套接字注册了一个额外的事件处理程序。相反,您应该在初始化时只注册一个处理程序,并且只在 getData 中注册 emit

【讨论】:

谢谢!!你的意思是这样的,例如client.jsstore = createStore(...) 之后:socket.on("responseData", function(data) store.dispatch(type: "GET_DATA", payload: data); ); 类似的东西,是的。您还可以为其创建一个 thunk 操作并在初始化期间分派一次。这在一定程度上取决于您的项目的组织方式。 OK 完美。它正在工作。尚未使用 thunk 操作。会调查的。非常感谢!!

以上是关于redux dispatch 多次触发的主要内容,如果未能解决你的问题,请参考以下文章

自己简写一个redux(redux源码简写)

如何在 Redux 中更新状态后触发回调?

redux的使用

Redux

Redux

Redux-thunk - dispatch 不是一个函数