尽管触发了动作,redux 状态仍未更新

redux state not updating despite action firing

请问我的 redux store 遇到了一些我不理解的行为。

尽管从 js class.

调用了 reducer,但我的 store.dispatch 没有触发更改

我的店铺如下:

const persistedReducer = persistReducer(persistConfig, reducers);

export default () => {
    const store = createStore(
        persistedReducer,
        composeWithDevTools(
            applyMiddleware(thunk),
            // other store enhancers if any
        )
    );
    const persistor = persistStore(store);
    store.subscribe(() => console.log("An action has ben fired here "));
    return { store, persistor }
}

我在 Axios 中间件中导入的 class 如下所示

const { store } = storeConfig();

然后我用它来发送一个动作

store.dispatch(toggleNotification(notification));

令我惊讶的是,尽管调用了 reducer,但状态从未得到更新 我在

添加了一个控制台
case TOGGLE_NOTIFICATION: {
    console.log("Does it reach the reducer ?", action.notification)
    return state.set("notification", fromJS(action.notification));
}

消息被我的操作触发

export function toggleNotification(notification: NotificationProps) {
    return { 
        type: constants.TOGGLE_NOTIFICATION, 
        notification,
    }
}

令我惊讶的是,通知状态永远不会更新,而且我的 redux 开发工具没有注册 TOGGLE_NOTIFICATION 类型的操作,而是注册了所有其他操作。

请问我错过了什么,为什么我的动作没有正确触发? 只有当我从 store.dispatch

开火时才会发生这种情况

如有任何帮助,我们将不胜感激

那是因为你正在做一个状态突变而不是 returning 一个全新的 state 对象。

Redux 遵循JavaScript 原则,对象可以在内存中共享同一个引用。因此,如果您正在对现有对象进行更新,例如:

return state.set("blah")

Redux 不会将其注册为一个全新的 state,因为这是同一个对象 returned.

不完全清楚你的代码在做什么,但我们可以在你应该总是创建或return一个全新的state对象的前提下操作。

我们可以通过在使用任何方法之前深度克隆初始状态对象来解决这个问题。

case TOGGLE_NOTIFICATION: {
            const newState = JSON.parse(JSON.stringify(state))
            return newState.set("notification", fromJS(action.notification));
        }

我认为问题在于您将商店配置包装在一个函数中:

export default () => {
    const store = createStore(...)
    return { store, persistor }
}

因此,当您在 Axios 中间件中的 const { store } = storeConfig(); 中调用它时,您正在创建一个新的商店对象,这可能不是您应用程序其余部分中使用的对象。

所以你可以删除这个函数,像这样:

const persistedReducer = persistReducer(persistConfig, reducers);

const store = createStore(
    persistedReducer,
    composeWithDevTools(
        applyMiddleware(thunk),
        // other store enhancers if any
    )
);
const persistor = persistStore(store);
store.subscribe(() => console.log("An action has ben fired here "));

export default { store, persistor }

然后像这样使用同一家商店:

import storeConfig from './path/to/storeConfig';

const { store } = storeConfig;
store.dispatch(toggleNotification(notification));

我在这方面犯了一个非常愚蠢的错误,我相信没有人会犯这种愚蠢的错误,但无论如何这里还有另一个错误可能会阻止 redux 状态在你的 reducer 上更新:

return {foo:"new value", ...state}
如果 foo 已经存在于先前的状态,

将不会更新您的状态。因此,与其这样,不如先添加状态,然后像这样更新 foo

return {...state, foo:"new value"}

编码愉快...