I tried to follow the documentation and this is what I did
middleware/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;
userEpic.ts (this is where API call should be but I made this this way just to test it if it is working)
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;
And I have some component where I trigger loginUser
and then try to console log it from the 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"
Looks like the redux store is not changing, loginUser
action is triggering but looks like ofType(LOGIN_USER)
is not catching it, I saw in some other thread and documentation to use filter(actionFunction.match),
instead of ofType
, but I think that is only for redux actions? And when I use the filter I get an error that is deprecated.