已经提出了非常类似的问题,但都不起作用,或者与我的情况不同。
我的目标:我想在我的redux Observable史诗中将"/login"路由更改为"/"路由。我想做一个简单的登录,当身份验证成功时,它应该转到主页。
我已经尝试过:简单使用"连接的反应路由器"中的{推送};方法类似于mapTo(push('/login'((,但位置已更改,但仍停留在登录页面上。我还设法注入了历史对象,但出现了"TypeError:无法读取未定义的属性'type'"错误。我还试着将连接的react路由器版本降级为其他线程中建议的版本,但这也无济于事。
我是Redux Observable的新手,所以我可能会错过一些非常基本的东西,但我真的找不到好的例子。
以下是我史诗中的相关代码:
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;
}
历史.ts:
import { createBrowserHistory } from 'history';
export const history = createBrowserHistory();
应用程序:
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>
);
}
非常感谢您的帮助!
我似乎错过了一些基本的东西。解决方案是我在App.tsx:中使用BrowserRouter
<Provider store={store}>
<BrowserRouter basename={basename}>
<Routes />
</BrowserRouter>
</Provider>
但我应该这样使用ConnectedRouter:
<Provider store={store}>
<ConnectedRouter history={history}>
<Routes />
</ConnectedRouter>
</Provider>