如何解决“错误:Reducers可能不会分派动作。”在我的ReactJS Redux应用程序中?

时间:2019-01-28 20:32:16

标签: javascript reactjs redux react-redux

我正在使用我的笔记应用程序。我想在登录后从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
    } });
  }
});

}

如果有人需要更多信息/代码,或者不清楚,请让我知道,我将进一步解释/显示。

预期结果:Expected result 实际结果:Actual result

错误:减速器可能无法调度动作。

3 个答案:

答案 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的调度。