反应路由器重定向但不使用redux进行渲染

时间:2017-10-20 14:49:38

标签: reactjs redux react-router react-redux react-router-redux

我正在尝试创建一个登录页面,该页面将在成功验证后重定向到主页。这是代码。

routes.js

const createRoutes = (store, history) => {
  return (
    <Router history={history}>
      <div>
        <AppLayout/>
        <Route exact path="/" component={Home}/>
        <Route path="/login" component={LoginContainer}/>
        <Route path="/register" component={RegisterContainer}/>
      </div>
    </Router>
  );
};

export default createRoutes;

actions.js

export const login = (data, successPath) => {
  return (dispatch) => {
    dispatch(beginLogin());

    return makeUserRequest("post", "/login", data)
      .then((resp) => {
        if (resp.data.success) {
          dispatch(loginSuccess(data));
          browserHistory.push(successPath);
        } else {
          dispatch(loginError(resp.data));
        }
      })
      .catch(console.error);
  };
};

Login.js

class Login extends React.Component {
  login = (event) => {
    event.preventDefault();

    const email = event.target.querySelector("input[name='email']").value;
    const password = event.target.querySelector("input[name='password']").value;

    this.props.login({
      email,
      password
    }, this.props.nextPathName);
  }

  render() {
    return (
      <div className="Login">
        <h2>Login</h2>
        <form onSubmit={this.login}>
          <input type="email" name="email" placeholder="Email"/>
          <input type="password" name="password" placeholder="Password"/>
          <input type="submit" value="Login"/>
          <h1>{this.props.user.email}</h1>
        </form>
      </div>
    );
  }
}

Login.propTypes = {
  login: PropTypes.func.isRequired,
  user: PropTypes.object.isRequired,
  nextPathName: PropTypes.string.isRequired
};

export default Login;

LoginContainer.js

const mapStateToProps = (state, ownProps) => {
  let nextPathName = "/";
  try {
    nextPathName = ownProps.location.state.nextPathName;
  } catch(err) {
    // ignore
  }
  return {
    user: state.user,
    nextPathName
  };
};

export default withRouter(connect(mapStateToProps, userActions)(Login));

reducer.js

// reducer for user actions
const user = (state = { isWaiting: false, authenticated: false, email: "", message: "" }, action) => {
  switch(action.type) {
  case REGISTER_USER:
    return { ...state, isWaiting: true };
  case REGISTER_SUCCESS_USER:
    return { ...state, isWaiting: false, message: action.data.message };
  case REGISTER_ERROR_USER:
    return { ...state, isWaiting: false, message: action.data.message };
  case LOGIN_USER:
    return { ...state, isWaiting: true };
  case LOGIN_SUCCESS_USER:
    return { ...state, isWaiting: false, authenticated: true, email: action.data.email };
  case LOGIN_ERROR_USER:
    return { ...state, isWaiting: false };
  default:
    return state;
  }
};

export default user;

export default combineReducers({
  user,
  routing: routerReducer
});

登录功能正常工作,当我点击登录按钮时,组件中的电子邮件正确打印。之后,浏览器将更改为新位置“/”,但页面未呈现,即即使在浏览器位置发生变化后视图仍保持相同。我已经在stackoverflow上查看了类似的问题答案,但是没有找到解决我问题的方法。我甚至使用withRouter但没有解决方案。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

如果您的网络/应用程序托管在动态服务器上,我认为您应该使用其中一个更高级别的路由器组件,例如:<BrowserRouter> 如果您的网站/应用程序托管在静态服务器上,则为<HashRouter>

routes.js

import {BrowserRouter, Route} from 'react-router-dom';
const createRoutes = (store, history) => {
  return (
    <BrowserRouter>
      <div>
        <AppLayout/>
        <Route exact path="/" component={Home}/>
        <Route path="/login" component={LoginContainer}/>
        <Route path="/register" component={RegisterContainer}/>
      </div>
    <BrowserRouter>
  );
};

export default createRoutes;

<BrowserRouter>只是一个包含预建历史的包装器,因此您可以对自定义历史记录实例执行相同操作。您可以阅读更多Here

答案 1 :(得分:0)

您可以使用React Router附带的漂亮的声明性push组件,而不是使用命令式<Redirect />方法:

{user.authenticated && <Redirect to={nextPath} />}

您可以将它放在任何有意义的地方。在您的登录组件内或顶层(只是确保不要反复重定向)