Javascript 在操作中多次触发React本机/Redux调度
我正在制作一个React/Redux应用程序。在我的一个动作中,Javascript 在操作中多次触发React本机/Redux调度,javascript,reactjs,react-native,redux,Javascript,Reactjs,React Native,Redux,我正在制作一个React/Redux应用程序。在我的一个动作中,dispatch在没有明显原因的情况下被调用时会触发6-8次。请参见下面我的组件的操作文件中的addMarkersRequestAddress: export function addMarkersSuccess(response) { return { type: 'addMarkersSuccess', status: 'success', response: response, receiv
dispatch
在没有明显原因的情况下被调用时会触发6-8次。请参见下面我的组件的操作文件中的addMarkersRequestAddress
:
export function addMarkersSuccess(response) {
return {
type: 'addMarkersSuccess',
status: 'success',
response: response,
receivedAt: Date.now(),
};
}
export function addMarkersFailure(error) {
return {
type: 'addMarkersFailure',
status: 'error',
error: error,
receivedAt: Date.now(),
};
}
export function addMarkersRequestCoordinates(submitFormData) {
// Why is this always returning addMarkersFailure? Is it possibly related to why it always fires multiple times?
// Same code as in virtualFenceWalk actions
return (dispatch) => {
console.log('running addMarkersRequestCoordinates');
console.log('submitFormData: ',submitFormData);
let JSONbody = JSON.stringify(submitFormData);
console.log('JSONbody: ',JSONbody);
fetch('http://localhost:8080/virtualFence', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSONbody
}).then(function(response){
dispatch(addMarkersSuccess(response));
}).catch(function(error) {
dispatch(addMarkersFailure(error));
});
}
}
export function addMarkersRequestAddress(submitFormData) {
return (dispatch) => {
console.log('running addMarkersRequestAddress');
console.log('submitFormData: ',submitFormData);
let JSONbody = JSON.stringify(submitFormData);
console.log('JSONbody: ',JSONbody);
// Make a request to a backend route that gets the coordinates from the Google Maps API
fetch('http://localhost:8080/virtualFenceAddress', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSONbody
}).then(function(response){
console.log('addMarkersRequestAddress success');
console.log('response: ',response);
dispatch(addMarkersSuccess(response));
}).catch(function(error) {
console.log('addMarkersRequestAddress failure');
console.log('error: ',error);
dispatch(addMarkersFailure(error));
});
}
}
当此代码运行时,addMarkersSuccess
将触发6-8次。它在某种程度上与dispatch
相关,因为如果我删除dispatch
调用并只保留控制台日志,addMarkersSuccess
会按预期触发一次,就是这样。它似乎与fetch
或异步性无关,因为如果删除fetch
并在函数主体中尝试相同的操作,则会出现相同的结果
下面是包裹组件的容器(因为我已经将其缩小到如何调用调度
的问题,因为如果没有调度
操作的其他部分只触发一次,那么可能存在如何在此处设置调度
的问题):
请注意,我真的不知道这个文件在做什么。我开始使用这个应用程序,所以这个文件是从那里。如果需要在那里进行更改,如果您能详细说明这些更改的具体用途,我们将不胜感激
编辑1:最初写这篇文章时,第一篇文章之后的所有文章都会抛出错误。在应用程序的其他部分做了一些进一步的工作之后,现在所有的额外触发都成功了。然而,基本问题(多次开火的原因)仍然存在
编辑2:添加了包装组件的容器。在
addMarkersRequestAddress
操作中,尝试在中返回分派
。然后()
.then((response) => {
dispatch(addMarkersSuccess(response));
}).catch((error) => {
dispatch(addMarkersFailure(error));
});
这可能会起作用。调用事件时是否使用preventDefault()。可能是这样的:
function ActionLink() {
function handleClick(e) {
e.preventDefault();
console.log('The link was clicked.');
}
return (
<a href="#" onClick={handleClick}>
Click me
</a>
);
}
函数ActionLink(){
函数handleClick(e){
e、 预防默认值();
log('已单击链接');
}
返回(
);
}
使用preventdefault在加载页面时不允许调用方法
<Button title="Add form field" onPress={this.addFormField}></Button>
<Button title="Delete form field" onPress={this.deleteFormField}></Button>
<Button
title="Submit markers"
onPress={(argument)=>addMarkersRequestAddress(this.refs.form.getValue())}
/>
addMarkersRequestAddress(this.refs.form.getValue())}
/>
因此您声明:
addMarkersSuccess
将触发一次,然后触发几次addMarkersFailure
addMarkersFailure
仅在出现错误时调用。当然,此错误包含解决问题所需的所有信息。特别是,它有一个堆栈,不仅指示错误发生的确切位置,而且还有一个完整的调用堆栈,指示导致错误的整个调用链
当一个承诺有几个阶段时,每个阶段都有失败的机会。任何阶段之后的捕获将传递错误
因此:
在您的情况下,可能是dispatch
引发了。现在,dispatch
本身没有什么问题,但是当它调用您的reducer时,reducer可能做了一些错误并抛出了一个错误。这反过来会导致调用.catch
回调(也称为拒绝处理程序)
因为您没有包含reducer代码,所以我无法指出其中的错误。但是,您应该能够通过检查错误消息和堆栈来找到它。问题的原因是在调用helper函数的文件中。我没有怀疑这个文件与这个问题有任何关系,所以我没有发布它。对于初始状态对象中有多个键的组件,我错误地认为我必须为每个键进行导入,而实际上我需要为每个reducer文件进行一次导入。我从virtualFence
reducer导入了六个变量,每个变量都导致dispatch
触发
这是不正确的版本:
import { combineReducers } from 'redux';
import nav from './nav';
import virtualFence from './virtualFence';
import latitude from './virtualFence';
import longitude from './virtualFence';
import latitudeDelta from './virtualFence';
import longitudeDelta from './virtualFence';
import markers from './virtualFence';
export default combineReducers({
nav,
latitude,
longitude,
latitudeDelta,
longitudeDelta,
markers,
virtualFence,
});
import { combineReducers } from 'redux';
import nav from './nav';
import virtualFence from './virtualFence';
export default combineReducers({
nav,
virtualFence,
});
这是正确的版本:
import { combineReducers } from 'redux';
import nav from './nav';
import virtualFence from './virtualFence';
import latitude from './virtualFence';
import longitude from './virtualFence';
import latitudeDelta from './virtualFence';
import longitudeDelta from './virtualFence';
import markers from './virtualFence';
export default combineReducers({
nav,
latitude,
longitude,
latitudeDelta,
longitudeDelta,
markers,
virtualFence,
});
import { combineReducers } from 'redux';
import nav from './nav';
import virtualFence from './virtualFence';
export default combineReducers({
nav,
virtualFence,
});
您能否演示如何在组件中使用这些操作?请出示证件。请注意“complete”一词。我已从调用此操作的组件中添加了呈现函数。请阅读我在前面的评论中给出的链接。您在哪里执行addMarkersRequestCoordinates函数?你的行动似乎还可以。我确实读了链接。有什么问题吗?我已经在then()
中返回了dispatch
。你的观点是使用胖箭头函数吗?我的观点是以某种方式返回调度
,因为函数似乎没有返回。除了使用胖箭头函数外,你的代码与我的代码没有任何不同。我认为你应该返回对函数的响应:尝试此返回('http://localhost:8080/virtualFenceAddress“,…
使用return
时仍然保持相同的行为。我没有包括reducer代码,因为即使reducer的整个内容只是返回状态
,也会发生错误。因此,我觉得我已经可靠地确定了reducer本身不是问题。无论如何,这是错误的没有真正说明为什么调度调用第一次实际工作。你检查过错误吗?错误消息是什么?今天早上再试一次——没有收到错误,我成功地调度了6次。自从最初发布此消息以来,我对代码做了一些进一步的工作。这些额外的工作主要与inco有关在应用程序的整个流程中重新调整Immutable.js的用途,这样可能在某种程度上解决了导致失败的原因。但是多重分派问题仍然存在,这就是需要解决的问题。这并不能解决它。我使用e.preventDefault()创建了一个名为onPress
的包装函数
然后调用了addMarkersRequestAddress
,但仍有多个调度。
import { combineReducers } from 'redux';
import nav from './nav';
import virtualFence from './virtualFence';
import latitude from './virtualFence';
import longitude from './virtualFence';
import latitudeDelta from './virtualFence';
import longitudeDelta from './virtualFence';
import markers from './virtualFence';
export default combineReducers({
nav,
latitude,
longitude,
latitudeDelta,
longitudeDelta,
markers,
virtualFence,
});
import { combineReducers } from 'redux';
import nav from './nav';
import virtualFence from './virtualFence';
export default combineReducers({
nav,
virtualFence,
});