我正在使用我的笔记应用程序。我想在登录后从Firebase加载笔记,成功登录后会显示笔记。
但是,当我添加注释时,应用程序会显示“错误:Reducers可能不会调度动作。”。我该如何解决这个问题?由于我需要在添加注释时进行聆听,并将收到的注释添加到我的应用列表中。不管错误如何,都会添加注释。
我知道错误的含义,但是没有办法解决。每当从Firebase添加笔记时,我都需要加载笔记。
此行引发错误:
store.dispatch({type: "DB_NOTE_ADDED", payload: {
notes: previousNotes
}});
我的减速器代码:
const initialState = {
SCREEN_CURRENT: "home",
authenticated: false,
database: app.database().ref().child('notities'),
notes: Array(0),
loading: true,
username: "",
email: "",
displayName: ""
}
const reducer = (state = initialState, action) => {
console.log("Reducer running", action.type);
switch(action.type){
case "AUTH_LOGIN":
if(action.payload.login === true){
state = {
...state,
authenticated: true,
username: action.payload.username,
email: action.payload.email,
displayName: action.payload.displayName,
}
const previousNotes = Array(0);
app.database().ref().child('notities').on('child_added', snap => {
if(snap.val().username === state.email){
console.log("DB_ADDED");
previousNotes.push({
id: snap.key,
noteContent: snap.val().noteContent,
modifiedDate: snap.val().modifiedDate
});
previousNotes.sort(function(a, b){
if(a.modifiedDate > b.modifiedDate){
return -1;
}
if(a.modifiedDate < b.modifiedDate){
return 1;
}
return 0;
});
console.log("previousNotes", previousNotes);
store.dispatch({type: "DB_NOTE_ADDED", payload: {
notes: previousNotes
}});
/* Below does not work (I already tried)
state = {
...state,
notes: previousNotes,
loading: false
}
*/
}
});
} else {
state = {
...state,
authenticated: false,
username: "",
email: "",
displayName: ""
}
}
break;
return state;
}
在我的App.js
内,触发“ AUTH_LOGIN”的调度动作:
componentWillMount(){
const previousNotes = Array(0);
this.removeAuthListener = app.auth().onAuthStateChanged((user) => {
if(user){
let displayName = (user.displayName != null ? user.displayName : user.email.slice(0, user.email.indexOf("@")));
let username = (user.username === undefined ? user.email : user.username);
let email = user.email;
console.log(displayName);
console.log(username);
store.dispatch({ type: "AUTH_LOGIN", payload: {
username, email, displayName, login: true
} });
} else {
store.dispatch({ type: "AUTH_LOGIN", payload: {
login: false
} });
}
});
}
如果有人需要更多信息/代码,或者不清楚,请让我知道,我将进一步解释/显示。
预期结果:
实际结果:
错误:减速器可能无法调度动作。
答案 0 :(得分:1)
实际上应该从操作文件而不是从reducer触发调度。在实际操作中,您应该向Firebase请求。从Firebase返回数据后,您应该从操作中分派,在reducer中,您应该处理或分配该数据以存储变量。
如有任何疑问,请告诉我。
谢谢
答案 1 :(得分:0)
我再次找到了答案。但是为什么这样做会起作用呢?
https://github.com/reduxjs/redux-thunk/issues/122
我应该使用以下代码:
// store.dispatch({type: "DB_NOTE_ADDED", payload: { notes: previousNotes }}); // Error: Reducers may not dipatch actions
setTimeout(() => { store.dispatch({type: "DB_NOTE_ADDED", payload: { notes: previousNotes }}); }); // I should use this code
答案 2 :(得分:0)
因为setTimeout创建了一个单独的线程。无论从何处调用它都无所谓,它只是调度您所调用的任何东西。任何调度总是触发并跳到减速器。通常,如果调度开始直接从reducer调用,那么它将是一个无限循环,在该循环中它将一次又一次地调用reducer。这就是为什么我们不应该触发来自reducer的调度。