我有一个相当标准的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()
获得的状态,但是似乎没有任何方法可以像我期望的那样工作来。
答案 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;
}
};