史诗在Redux可观察对象中不触发



我试着遵循文档,这就是我所做的

中间件/index.ts

import { combineEpics } from "redux-observable";
import userEpic from "./userEpic";
export const rootEpic = combineEpics(
userEpic,
);

store.ts

import { configureStore } from "@reduxjs/toolkit";
import { createEpicMiddleware } from "redux-observable";
import { rootEpic } from "../middleware";
import userReducer from "./reducers/userSlice";
const rootReducer = {
user: userReducer,
};
const epicMiddleware = createEpicMiddleware();
export const store = configureStore({
reducer: rootReducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat(epicMiddleware),
});
epicMiddleware.run(rootEpic);
export type RootStateType = ReturnType<typeof store.getState>;
export type AppDispatchType = typeof store.dispatch;
export default store;

actions.ts

export const LOGIN_USER = "LOGIN_USER";
export const loginUser = () => {
return {
type: LOGIN_USER,
} as const;
};
export type LoginUserAction = ReturnType<typeof loginUser>;

userEpic。ts(这是API调用应该在哪里,但我这样做只是为了测试它是否工作)

import { Action } from "@reduxjs/toolkit";
import { Observable } from "rxjs";
import { combineEpics, ofType } from "redux-observable";
import { LOGIN_USER } from "./actions";
import { map } from "rxjs/operators";
import { setUserData } from "../../redux/reducers/userSlice";
const fetchUserEpic = (action$: Observable<Action>) => {
return action$.pipe(
ofType(LOGIN_USER),
map(() =>
setUserData({
id: 12,
name: "test",
surname: "test",
username: "test",
refreshToken: "test",
accessToken: "test",
})
)
);
};
export default combineEpics(fetchUserEpic);

userSlice.ts

import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { FetchStatus } from "../../modules/types";
import { RootStateType } from "../store";
type UserType = {
id: number;
name: string;
surname: string;
username: string;
refreshToken: string;
accessToken: string;
};
type UserStateType = {
user: UserType | null;
userFetchStatus: FetchStatus;
};
const initialUserState: UserStateType = {
user: null,
userFetchStatus: FetchStatus.success,
};
export const userSlice = createSlice({
name: "user",
initialState: initialUserState,
reducers: {
setUserData: (state, action: PayloadAction<UserType>) => {
state.user = action.payload;
state.userFetchStatus = FetchStatus.success;
},
setUserFetchingStatus: (state, action: PayloadAction<FetchStatus>) => {
state.userFetchStatus = action.payload;
},
clearUserData: () => {
return initialUserState;
},
},
extraReducers: (builder) => {
builder.addDefaultCase((state) => {
return state;
});
},
});
export const { setUserData, clearUserData } = userSlice.actions;
export const getUserData = (state: RootStateType) => state.user;
export default userSlice.reducer;

我有一些组件,我触发loginUser,然后尝试从redux控制台日志

component.ts

const dispatch = useAppDispatch()
const user = useAppSelector(getUserData);
console.log(user)
<TouchableOpacity onPress={() => dispatch(loginUser)}>
//...

package.json

"react-redux": "^8.0.1",
"redux": "^4.2.0",
"redux-observable": "^2.0.0"

看起来redux存储没有改变,loginUser动作触发但看起来ofType(LOGIN_USER)没有捕捉到它,我在其他一些线程和文档中看到使用filter(actionFunction.match),而不是ofType,但我认为这仅适用于redux动作?当我使用过滤器时,我得到一个已弃用的错误。

你必须调用你的动作创建者:

dispatch(loginUser()),而不是dispatch(loginUser)

除此之外,你绝对不应该手写动作创建器——如果你不想用createSlice来做,至少用createAction来做。

export const loginUser = createAction('user/login').

那么你也可以使用filter(loginUser.match)

最新更新