redux dispatch 多次触发
redux dispatch fires multiple times
我在 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);
我哪里做错了或预期错了?非常感谢您的帮助!
您正在为每个 getData
调用的套接字注册一个额外的事件处理程序。相反,您应该在初始化时只注册一个处理程序,并且只在 getData
.
中注册 emit
在我的例子中,我使用的是 redux-saga,我的 saga 中间件触发了很多次,即使动作只触发了一次。我改变了我的传奇效果:
export default function* watchLogin() {
while(true) {
yield takeEvery(LOGIN, serverCreateInitialUser);
}
}
对此:
export default function* watchLogin() {
yield takeLatest(LOGIN, serverCreateInitialUser);
}
这不完全是问题的答案,但由于我遇到了类似的问题而发现了这个问题,希望它能对某人有所帮助。
我在 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);
我哪里做错了或预期错了?非常感谢您的帮助!
您正在为每个 getData
调用的套接字注册一个额外的事件处理程序。相反,您应该在初始化时只注册一个处理程序,并且只在 getData
.
emit
在我的例子中,我使用的是 redux-saga,我的 saga 中间件触发了很多次,即使动作只触发了一次。我改变了我的传奇效果:
export default function* watchLogin() {
while(true) {
yield takeEvery(LOGIN, serverCreateInitialUser);
}
}
对此:
export default function* watchLogin() {
yield takeLatest(LOGIN, serverCreateInitialUser);
}
这不完全是问题的答案,但由于我遇到了类似的问题而发现了这个问题,希望它能对某人有所帮助。