首页 > 解决方案 > 登录成功时如何在redux saga中路由跳转?

问题描述

感谢您检查这个问题。我是新来的反应。我使用 react hooks 和 redux-saga。我希望路由器/home在登录成功时跳转到。我使用connected-react-routerandhistory来做到这一点,这是一种常用的方法吗?请告诉我是否有更好的方法。现在当我登录成功时。页面不会跳转到“/home”。这是我的代码。

reducer.ts

const initialUser = (): UserState => {
  const token = TokenStorage.getToken();
  if (token === null) {
    return { isAuthenticated: false };
  }
  return UserModel.getUser(token);
};

function user(state = initialUser(), action: UserAction): UserState {
  switch (action.type) {
    case LOGIN_SUCCESS:
      return { ...state, ...action.payload };
    case LOGIN_FAILED:
      TokenStorage.clear();
      return { isAuthenticated: false };
    default:
      return state;
  }
}

export const createRootReducer = (history: History) =>
  combineReducers({
    router: connectRouter(history),
    user,
  });

// when add router into combineReducers. the RootState is wrong.. how to fix?
export type RootState = ReturnType<typeof createRootReducer>;

存储/索引.ts

export default function configureStore(history: History) {
  const sagaMiddleware = createSagaMiddleware();
  const composeEnhancers =
    (typeof window === 'object' &&
      window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) ||
    compose;

  const store = createStore(
    createRootReducer(history),
    composeEnhancers(applyMiddleware(sagaMiddleware, routerMiddleware(history)))
  );

  sagaMiddleware.run(rootSaga);
  return store;
}

sagat.ts

function* LoginRequestSaga(username: string, password: string) {
  try {
    const result: ILoginResponseData = yield call(
      fetchLogin,
      username,
      password
    );
    if (result.code === '1') {
      TokenStorage.storeToken(result.token);
      message.success(result.msg);
      const user = UserModel.getUser(result.token);
      yield put(loginSuccess(user));
      yield put(push('/home'));    <----- this line doesn't run....
    } else {
      message.error(result.msg);
      yield put(loginFailed());
    }
  } catch (err) {
    message.error(err);
    yield put(loginFailed());
  }
}

索引.ts

export const history = createBrowserHistory();
export const store = configureStore(history);

ReactDOM.render(
  <Provider store={store}>
    <ConnectedRouter history={history}>
      <Router />
    </ConnectedRouter>
  </Provider>,
  document.getElementById('root')
);

我的路由器

const renderRoutes = routes.map(({ path, exact, component, key }) => (
  <Route exact={exact || false} path={path} key={key} component={component} />
));

const Routers: React.FC = () => (
  <BrowserRouter>
    <Suspense fallback={<Loading />}>
      <Switch>{renderRoutes}</Switch>
    </Suspense>
  </BrowserRouter>
);

如果您想查看更多详细信息,可以查看此repo 谢谢大家。

标签: reactjstypescriptredux-saga

解决方案


好吧,我有一个非常相似的项目,登录方法相同(使用 redux-saga)。为了实现重定向,我在我的Login.js组件中使用了这个方法:

const history = useHistory()
const { isLogged, state } = useSelector(state => ({
    isLogged: state.logged.isLogged,
    state: state.login,
}))

if(isLogged) {
    history.push(routes.dashboard)
}

基本上我将它存储isLogged到一个 reducer 中,并在Login.js组件中检查它。

希望这可以帮助。


推荐阅读