反应路由器 dom 重定向问题。更改 url,不渲染组件

Posted

技术标签:

【中文标题】反应路由器 dom 重定向问题。更改 url,不渲染组件【英文标题】:React router dom redirect problem. Changes url, does not render component 【发布时间】: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.loguseEffect() 它发生两次,我假设是第一次,当我使用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.1react-router同理,5.0.1

【问题讨论】:

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

您的代码中有两个错误。

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

    您正在使用本地存储在组件之间交换信息。但是本地存储中的更改是不可见的,因此它不会触发组件重新渲染。要纠正这个问题,您应该在 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

【讨论】:

以上是关于反应路由器 dom 重定向问题。更改 url,不渲染组件的主要内容,如果未能解决你的问题,请参考以下文章

反应测试库:测试路由器重定向

登录后反应路由器导航

反应路由器 - 登录后重定向

反应路由器 - 登录后重定向

反应路由器 v4 重定向不起作用

React 路由器推送仅更改 url