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

时间:2019-09-14 05:51:33

标签: reactjs redux immutable.js

我在我的redux存储中遇到了一些我不理解的行为。

尽管从js类调用了reducer,我的Can't determine type for tag ' <library name="Gradle: com.google.android.gms:play-services-tasks:19.0.0@aar"> <CLASSES> <root url="jar://$PROJECT_DIR$/../.gradle/caches/transforms-2/files-2.1/75185506230655574b8334cb643643f0/play-services-tasks-17.0.0/jars/classes.jar!/"/> <root url="file://$PROJECT_DIR$/../.gradle/caches/transforms-2/files-2.1/75185506230655574b8334cb643643f0/play-services-tasks-17.0.0/res"/> </CLASSES> <JAVADOC/> <SOURCES/> </library>' 仍未触发更改。

我的商店如下:

store.dispatch

我在下面的Axios中间件类中导入了

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 }
}

然后我用它来调度动作

const { store } = storeConfig();

令我惊讶的是,尽管调用了reducer,该状态从未得到更新 我在以下位置添加了一个控制台

store.dispatch(toggleNotification(notification));

消息被我的动作触发

case TOGGLE_NOTIFICATION: {
    console.log("Does it reach the reducer ?", action.notification)
    return state.set("notification", fromJS(action.notification));
}

令我惊讶的是,通知状态从未更新,而且我的redux dev工具没有注册export function toggleNotification(notification: NotificationProps) { return { type: constants.TOGGLE_NOTIFICATION, notification, } } 类型的操作,但注册了所有其他操作。

请问我缺少什么,为什么我的动作不能正确触发? 仅当我从TOGGLE_NOTIFICATION

射击时才会发生这种情况

任何帮助将不胜感激

3 个答案:

答案 0 :(得分:2)

那是因为您要进行状态突变,而不是返回全新的state对象。

Redux遵循JavaScript原则,即对象可以在内存中共享相同的引用。因此,如果要对现有对象进行更新,例如这样做:

return state.set("blah")

Redux不会将其注册为全新的state,因为返回的对象相同。

尚不清楚您的代码在做什么,但是我们可以在您始终创建或返回全新的state对象的前提下进行操作。

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

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

答案 1 :(得分:1)

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

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));

答案 2 :(得分:0)

我对此有一个非常愚蠢的错误,我敢肯定没有人会犯这种愚蠢的错误,但是无论如何,这是另一个可能阻止您的reducer上的redux状态更新的错误:

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

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

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

快乐的编码...