Невозможно выполнить маршрутизацию в Redux Observable epic - PullRequest
0 голосов
/ 19 февраля 2020

Уже заданы очень похожие проблемы, но ни одна из них не работает, или они отличаются от моего случая.

Моя цель: я хочу изменить маршрут '/ login' на '/' в моем избыточном наборе Observable epi c. Я хотел бы сделать простой вход в систему, и когда аутентификация прошла успешно, она должна go перейти на домашнюю страницу.

Что я уже пробовал: просто использовал {pu sh} из 'connected-реакции-router'; метод вроде mapTo (pu sh ('/ login')), но местоположение изменилось, но застряло на странице входа. Мне также удалось внедрить объект истории, но у меня возникла ошибка «TypeError: Невозможно прочитать свойство« тип »из неопределенного». Я также попытался понизить версию подключенного реагирующего маршрутизатора, как это было предложено в другом потоке, но это тоже не помогло.

Я очень новичок в Redux Observable, поэтому я мог бы пропустить очень базовый материал c, но я не смог найти хороших примеров.

Вот соответствующий код из моего эпи c:

const login: Epic = action$ =>
    action$.pipe(
        ofType(LOGIN),
        mergeMap(({ payload }) =>
            from(API.post<LoginResult>('/oauth/token', $.param({...payload, grant_type: "password"}),
                ({auth: {
                    username: 'xxxx',
                    password: 'xxxx'
                }})
            )).pipe(
                map(({ data }) => loginSuccessAction(data)),
                catchError(err => of(loginErrorAction(err)))
            )
        )
    );


const loginSuccess: Epic = (action$) =>
    action$.pipe(
        ofType(LOGIN_SUCCESS),
        map(({ data }) => fetchProfileAction(data))
    );


const fetchProfile: Epic = (action$, state$) =>
        action$.pipe(
        ofType(FETCH_PROFILE_REQUEST),
        mergeMap(({ payload }) =>
            from(API.get<Profile>('/REST/v1/profile', {headers: {'Authorization': "Bearer " + state$.value.auth.auth.accessToken}}
            )).pipe(
                map(({ data }) => fetchProfileSuccessAction(data)),
                catchError(err => of(loginErrorAction(err)))
            )
        )
    );

const fetchProfileSuccess: Epic = action$ =>
    action$.pipe(
        ofType(FETCH_PROFILE_SUCCESS),
        tap(({action}) => {console.log(action$); debugger;}),
        //mapTo(push('/login')) // if I do this then the url changes to '/' but I'm still stucked on the login page
        mapTo(history.push('/login')) // if I do this then I've got "TypeError: Cannot read property 'type' of undefined" error 
    );

cofigureStore.ts:

export function configureStore() {
    const epicMiddleware = createEpicMiddleware<
        AllActions,
        AllActions,
        AppState
    >();

    const store = createStore(
        rootReducer(history),
        composeWithDevTools(
            applyMiddleware(epicMiddleware, routerMiddleware(history))
        )
    );

    epicMiddleware.run(rootEpic);
    return store;
}

history.ts:

import { createBrowserHistory } from 'history';

export const history = createBrowserHistory();

App.ts:

export default function App() {

    let configureStore: Function;

    configureStore = require('./store/cofigureStore').configureStore;

    const store = configureStore();

    return (
        <Provider store={store}>
            <BrowserRouter basename={basename}>
                <Routes />
            </BrowserRouter>
        </Provider>
    );
}

Большое спасибо за любую помощь!

1 Ответ

0 голосов
/ 20 февраля 2020

Кажется, что я что-то пропустил, просто c. Решением было то, что я использовал BrowserRouter в своем App.tsx:

        <Provider store={store}>
            <BrowserRouter basename={basename}>
                <Routes />
            </BrowserRouter>
        </Provider>

Но я должен был использовать ConnectedRouter следующим образом:

        <Provider store={store}>
            <ConnectedRouter history={history}>
                <Routes />
            </ConnectedRouter>
        </Provider>
...