【问题标题】:react router redirects but does not render with redux反应路由器重定向但不使用 redux 渲染
【发布时间】:2018-04-01 18:43:20
【问题描述】:

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

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);
  };
};

登录.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,但没有解决方案。任何帮助将不胜感激。

【问题讨论】:

  • 你的减速机在哪里?
  • @PratheeshM 好的,我也在添加减速器代码。
  • reducer代码其实是分成了index.js和user.js两部分,我把它们加在一起了。希望可以理解。 @PratheeshM
  • 这段代码是什么` browserHistory.push(successPath);`
  • browserHistory 来自import { createBrowserHistory } from "history"; export default createBrowserHistory();

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


【解决方案1】:

如果您的网络/应用程序托管在动态服务器上,我认为您应该使用更高级别的路由器组件之一,例如:&lt;BrowserRouter&gt;&lt;HashRouter&gt; 如果您的网站/应用程序托管在静态服务器上

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;

&lt;BrowserRouter&gt; 只是一个带有预构建历史的包装器,因此您可以对自定义历史实例执行相同的操作。你可以阅读更多Here

【讨论】:

  • const history = syncHistoryWithStore(browserHistory, store); 但这段历史来自这里。不会使用 BrowserHistory 导致问题,因为我正在使用此历史记录来处理 redux。
【解决方案2】:

除了使用命令式 push 方法,您还可以使用 React Router 附带的漂亮的声明式 &lt;Redirect /&gt; 组件:

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

你可以把它放在对你有意义的地方。在您的登录组件内部或顶层(只是确保不要一遍又一遍地重定向)

【讨论】:

  • 我的意图是将其放入操作中,因为我也在注册期间重用了登录操作。我可以在 redux 操作代码中使用&lt;Redirect /&gt; 吗?
  • 没有重定向是一个组件。如果你把它放在你的routes.js文件中,你只需要写一次
猜你喜欢
  • 2021-09-06
  • 1970-01-01
  • 2019-12-30
  • 1970-01-01
  • 2020-07-05
  • 2023-03-06
  • 1970-01-01
  • 2019-10-03
相关资源
最近更新 更多