我配置了一个Redux存储,我正试图从React组件外部访问状态。我使用的是store.getState()
,但它会返回存储中所有内容的初始状态值,即使存储中填充了正确的数据(在UI和开发工具中可见(。似乎只是在导入存储并通过getState()
访问状态时,返回的是初始值,而不是存储中的实际值。下面的代码。
store.ts
import * as _ from "@reduxjs/toolkit/node_modules/redux-thunk";
import { Action, configureStore } from "@reduxjs/toolkit";
import { ThunkAction } from "redux-thunk";
import { useDispatch } from "react-redux";
import reducers from "./reducers";
const store = configureStore({
reducer: reducers,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
serializableCheck: false,
}),
});
export type AppDispatch = typeof store.dispatch;
export type IRootState = ReturnType<typeof store.getState>;
export type AppThunk = ThunkAction<void, IRootState, unknown, Action<string>>;
// Export a hook that can be reused to resolve types
export const useAppDispatch = () => useDispatch<AppDispatch>();
export default store;
我呼叫商店的服务:
import store from "store";
import { LoggingService } from "logger";
const logData(data) {
const user = store.getState().user;
LoggingService.log(user.email, data);
}
在上面的例子中,store.getState().user
返回一个对象,但email
为空。然而,email
实际上是填充的,正如在UI和开发工具中可以看到的那样。任何帮助都将不胜感激。
还需要注意的是,这不是一个SSR应用程序。
store.getState()
只从redux存储返回一次当前状态。通过分派操作对状态进行的后续更改将不会再次调用此方法,除非使用subscribe(listener(。
我们可以编写一个自定义的可观察存储实用程序,而不是直接使用store.subscribe
。为什么?参见问题#303
index.js
:
export function toObservable(store) {
return {
subscribe({ onNext }) {
let dispose = store.subscribe(() => onNext(store.getState()));
onNext(store.getState());
return { dispose };
},
};
}
如何使用它?让我们写一个测试来解释这一点:
import { combineReducers, createStore } from 'redux';
import { toObservable } from './';
const LoggingService = {
log: console.log,
};
describe('toObservable', () => {
test('should pass', () => {
function userReducer(state = { email: '' }, action) {
switch (action.type) {
case 'GET_USER_FULFILLED':
return { ...state, ...action.payload };
default:
return state;
}
}
const store = createStore(combineReducers({ user: userReducer }));
// create store observable somewhere, may be in the application initialization phase
const store$ = toObservable(store);
store$.subscribe({ onNext: (state) => LoggingService.log(state.user.email) });
// Later, dispatch action in component
store.dispatch({ type: 'GET_USER_FULFILLED', payload: { email: 'example@gmail.com' } });
});
});
测试结果:
PASS redux-toolkit-example packages/redux-toolkit-example/examples/observer-store/index.test.ts
toObservable
✓ should pass (23 ms)
console.log
at onNext (packages/redux-toolkit-example/examples/observer-store/index.test.ts:22:58)
console.log
example@gmail.com
at onNext (packages/redux-toolkit-example/examples/observer-store/index.test.ts:22:58)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 2.937 s
正如您所看到的,每次状态更改时,都会调用onNext
方法。
store.getState((不会立即更新。您必须在Functional Component中使用useSelector挂钩,才能从redux中获得更新的状态。类似:
const user = useSelector((state) => state.user);