尝试从外部React组件分派时清空Redux存储

时间:2020-05-11 16:02:00

标签: reactjs react-redux

我有一个相当标准的React-Redux设置,其中包含一些持久性。

app.jsx

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { PersistGate } from 'redux-persist/integration/react';
import AppRouter from './routers/AppRouter';
import configureStore from './store/configureStore';
import config from 'cgConfig';

const { store, persistor } = configureStore();

const jsx = (
    <Provider store={store}>
        <PersistGate loading={null} persistor={persistor}>
            <AppRouter />
        </PersistGate>
    </Provider>
);

ReactDOM.render(jsx, document.getElementById(config.constants.element.rootId));

configureStore.js

import {
    createStore,
    combineReducers
} from 'redux';
import {
    persistStore,
    persistReducer
} from 'redux-persist';
import autoMergeLevel2 from 'redux-persist/lib/stateReconciler/autoMergeLevel2';
import storage from 'redux-persist/lib/storage';

import config from 'cgConfig';

//...import reducers...

export default () => {
    const persistConfig = {
        key: 'root',
        storage,
        stateReconciler: autoMergeLevel2
    };

    let rootReducer = combineReducers({
        //...all of my reducers...
    });

    let store = undefined;
    let pr = persistReducer(persistConfig, rootReducer);

    if (config.env.includeReduxDevTools) {
        store = createStore(
            pr,
            window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
        );
    } else {
        store = createStore(pr);
    }

    let persistor = persistStore(store);

    return {
        store,
        persistor
    };
};

但是,有点不合常规的一件事是,我需要在react组件的上下文之外更新商店。据我了解(for example),这应该不太困难。只需调用configureStore()即可到达商店并运行store.dispatch(action)。问题是我一直在恢复商店的初始状态(IE空),这与通过登录等过程已经设置的状态不同。因此,当我运行dispatch时,则错误状态正在更新。

不确定我做错了什么,将对您有所帮助。

编辑以回答Uma关于路由器的外观问题:

首先介绍更多背景信息。我正在工作的网站基本上将产生类似于图形的形状。从各种来源(如上下文菜单和工具栏)中选择这些形状后,即可对其进行操作。我正在处理此更改事件。

进行更改时,所选项目的信息以及需要更改的内容将发送到通用函数,该通用函数将确定用于更新Redux商店的还原器/操作。我所有的异径管都遵循相同的模式,看起来像这样:

const reducerInitialState = {};

const setSomeProperty= (state, action) => {
    let newState = { ...state };

    newState.some_property = action.some_update;

    return newState;
};

export default (state = reducerInitialState, action) => {
    switch (action.type) {
        case 'UPDATE_SOME_PROPERTY':
            return setSomeProperty(state, action);
        case 'LOG_OUT':
            return { ...reducerInitialState };
        default:
            return state;
    }
};

为完整性而采取的行动:

export const setSomeProperty = update_data => ({
    type: 'UPDATE_SOME_PROPERTY',
    some_update: update_data
});

我拥有的通用函数如下所示:

import configureStore from './store/configureStore';
import { setSomeProperty} from './actions/SomeAction';
import API from './utilities/API';

export default async ({ newValue, selectedShape }) => {
    if (!newValue || !selectedShape)
        throw "Cannot update the server with missing parameters.";

    await API()
        .post(
            `/api/update-shape`,
            {
                newValue,
                shape: selectedShape
            }
        )
        .then(response => {
            updateValue({ selectedShape, newValue });
        })
        .catch(error => {
            // handle error
        });
}

const getAction = ({ shape }) => {
    switch (shape.type) {
        case 0:
            return setSomeProperty;
        default:
            throw `Invalid type of ${shape.type} attempting to update.`;
    }
}

const updateValue = ({ selectedShape, newValue }) => {
    const action = getAction({ shape: selectedShape })
    const { store } = configureStore();
    store.dispatch(action(newValue))
}

注意:API是Axios的包装。

自从昨天发布此帖子以来,我读到创建第二家商店,就像我对const { store } = configureStore();所做的那样,这是我的问题之一在于React / Redux不能有两个。我也已经意识到问题很可能与我的减速器中的初始状态有关,以某种方式使用configureStore()不会将实际状态发送给减速器,因此我的所有减速器都在以下情况下显示其初始状态:我使用console.log(store.getState());查看它们。如果这是真的,那么至少我知道问题所在,这是成功的一半,但是我不确定如何继续进行,因为我试图重新水化从configureStore()获得的状态,但是似乎没有任何方法可以像我期望的那样工作来。

1 个答案:

答案 0 :(得分:0)

据我所知,您最终陷入一个怪异的循环,在该循环中您调用操作setSomeProperty,然后将您转到化简器,然后在化简器中再次调用该setSomeProperty行动。

在减速器中,我希望看到这样的东西:

export default (state = reducerInitialState, action) => {
  switch (action.type) {
      case 'UPDATE_SOME_PROPERTY':
          return {
            ...state, // preserve already set state properties if needed
            some_update: action.some_update
          }
      case 'LOG_OUT':
          return { ...reducerInitialState };
      default:
          return state;
  }
};