【问题标题】:React router dom redirect problem. Changes url, does not render component反应路由器 dom 重定向问题。更改 url,不渲染组件
【发布时间】:2019-11-29 15:35:59
【问题描述】:

问题:当我使用history.push() 时,我可以看到浏览器更改了 url,但它并没有呈现我的组件在路径上侦听。只有在我刷新页面时才会呈现。

App.js文件:

import React from "react";
import { BrowserRouter as Router, Route } from "react-router-dom";
import { Provider } from "react-redux";
import PropTypes from "prop-types";

//Components
import LoginForm from "../LoginForm/LoginForm";
import PrivateRoute from "../PrivateRoute/PrivateRoute";
import ServerList from "../ServerList/ServerList";

const App = ({ store }) => {
  const isLoggedIn = localStorage.getItem("userToken");

  return (
    <Router>
      <Provider store={store}>
        <div className="App">
          {isLoggedIn !== true && (
            <Route exact path="/login" component={LoginForm} />
          )}
          <PrivateRoute
            isLoggedIn={!!isLoggedIn}
            path="/"
            component={ServerList}
          />
        </div>
      </Provider>
    </Router>
  );
};

App.propTypes = {
  store: PropTypes.object.isRequired
};

export default App;

在我的 LoginForm 中,我正在向 API 发出请求,在完成我的程序后,我使用 .then() 重定向我的用户:

.then(() => {
  props.history.push("/");
})

会发生什么:浏览器将 url 从 /login 更改为 /,但不会呈现侦听 / 路由的组件,除非我重新加载页面。

在我的/ 组件中,我使用useEffect() 钩子向API 发出另一个请求,它获取数据并将其打印到return() 中。如果我在console.log 内useEffect() 它发生两次,我假设是第一次,当我使用useState() 钩子将来自API 的数据存储在组件的状态内时。

编辑:按要求添加PrivateRoute 组件:

import React from "react";
import { Route, Redirect } from "react-router-dom";

const PrivateRoute = ({ component: Component, isLoggedIn, ...rest }) => {
  return (
    <Route
      {...rest}
      render={props =>
        isLoggedIn === true ? (
          <Component {...props} />
        ) : (
          <Redirect to={{ pathname: "/login" }} />
        )
      }
    />
  );
};

export default PrivateRoute;

我已经尝试过的: 1)用withRouter()包裹我的default export:

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(LoginForm));

2) 创建自定义history 并将其作为prop 传递给Router。

react-router-dom 版本是^5.0.1。 react-router同理,5.0.1

【问题讨论】:

  • 看起来你的PrivateRoute 总是挂载的。你需要显示privateroute组件
  • @Panther,将原帖更新为PrivateRoute。
  • 这看起来也像它的渲染.. 你能检查一下 React 调试器面板,看看什么没有渲染.. 问题会在那里

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


【解决方案1】:

您的代码中有两个错误。

  1. 您没有使用&lt;switch&gt; 组件来包装路由。因此,在每次渲染时都会处理所有路由,并且会渲染来自每个 &lt;route&gt; 的所有组件。

  2. 您正在使用本地存储在组件之间交换信息。但是本地存储中的更改是不可见的,因此它不会触发组件重新渲染。要纠正这个问题,您应该在 App 组件中使用本地状态(通过将其转换为类或使用挂钩)。

修正后的代码如下所示

const App = ({ store }) => {
  const [userToken, setUserToken] = useState(localStorage.getItem("userToken")); // You can read user token from local store. So on after token is received, user is not asked for login

  return (
    <Router>
      <Provider store={store}>
        <div className="App">
          <Switch>
            {!!userToken !== true && (
              <Route exact path="/login"
                render={props => <LoginForm {...props} setUserToken={setUserToken} />}
              />
            )}
            <PrivateRoute
              isLoggedIn={!!userToken}
              path="/"
              component={ServerList}
            />
          </Switch>
        </div>
      </Provider>
    </Router>
  );
};

并且LoginForm 应该使用setUserToken 来更改App 组件中的用户令牌。它还可以将用户令牌存储在本地存储中,因此页面刷新用户不会被要求登录,而是使用存储的令牌。

除了&lt;Route&gt; 之外,请确保不要在&lt;Switch&gt; 和&lt;/Switch&gt; 之间放置任何内容。否则路由将不起作用。

这里是working sample

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-02
    • 2019-08-27
    • 1970-01-01
    • 2021-09-06
    • 2020-06-21
    • 1970-01-01
    • 2017-12-23
    • 2018-07-26
    相关资源
    最近更新 更多