简体   繁体   English

React-router v4页面刷新不起作用

[英]React-router v4 Page Refresh Not Working

I am probably missing history or something but when I refresh a page on a sub route such as /login or any other routes I get: 我可能错过了历史记录或其他什么,但当我刷新子路径上的页面,如/login或任何其他路线,我得到:

403 Forbidden 403禁止

Code: AccessDenied Message: Access Denied RequestId: 075CAA73BDC6F1B9 HostId: O1n36xVCoeu/aLaSMrtCkAFZruWk5ZcO4RIrznEhvUxdu8lFEhL0XcKw2L4W4J7VYYet+HDv8tc= 代码:AccessDenied消息:访问被拒绝RequestId:075CAA73BDC6F1B9 HostId:O1n36xVCoeu / aLaSMrtCkAFZruWk5ZcO4RIrznEhvUxdu8lFEhL0XcKw2L4W4J7VYYet + HDv8tc =

Keep in mind the routes work fine as long as I don't refresh. 请记住,只要我不刷新,路线就可以正常工作。
So lets say I go to / (the homepage). 所以我想去/ (主页)。 On it, I have a hyperlink that maps to the path /login in my react-router routes. 在它上面,我有一个超链接 ,映射到我的react-router路由中的路径/login I click the hyperlink, it works fine, renders the /login control in react based on my react-router routes. 我单击超链接,它工作正常,根据我的react-router路由呈现/ login控件。 It's only when I refresh any page I'm on that I get the error above. 只有当我刷新任何页面时,我才会得到上面的错误。

Also when I sync my bucket I'm putting public read on it so not sure why I'm getting this permission error: 此外,当我同步我的存储桶时,我正在对其进行公开读取,因此不确定为什么我收到此权限错误:

aws s3 sync --acl public-read build s3://${bkt}

Here's an example of some routes and a component: 以下是一些路线和组件的示例:

      <Provider store={store}>
        <Layout>
          <Switch>
            <Route component={Home} exact path='/' />
            <ProtectedRoute component={
DashboardContainer} path='/dashboard' />
            <Route component={LoginContainer} path='/login' />
            <Route component={NotFound} path='*' />
          </Switch>
        </Layout>
      </Provider>

LoginContainer LoginContainer

    import { connect } from 'react-redux'
    import React, { Component } from 'react'
    const _ = require('lodash')

...

    import Login from '../components/auth/Login/Login'

    class LoginContainer extends Component {
      constructor(props) {
        super(props)

        this.handleEmailInput = this.handleEmailInput.bind(this)
        ... rest of the handlers
      }


      async handleLoginPressed(e) {
        e.preventDefault()
        this.validateForm()

        await this.props.authenticate(this.state.email, this.state.password)
        if(this.props.isAuthenticated) {
          this.props.history.push('/dashboard')
          return
        }

      ... more code

      render(){
        return(
          <div>
            <Login
              login={this.handleLoginPressed}
            />
          </div>
          )
      }
    }

    const mapStateToProps = state => ({
      token: state.auth.token
    })

    export const mapDispatchToProps = {
      authenticate: AuthAsyncActions.authenticate
    }

    export { Login }
    export default connect(mapStateToProps, mapDispatchToProps)(LoginContainer)

Now I've left out a bunch of repetitive code and this shows basically the only thing in here I have for routing is if they successfully log in, they're redirected to /dashboard . 现在我遗漏了一堆重复的代码,这基本上显示我在这里唯一的路由是,如果他们成功登录,他们被重定向到/dashboard My problem isn't that, redirect works fine. 问题不在于,重定向工作正常。 It's whenever I refresh on any page I'm on, it doesn't re-route again. 无论何时我在我正在打开的任何页面上刷新,它都不会再次重新路由。

This is because your server tries to go to that url directly. 这是因为您的服务器尝试直接转到该URL。 You have two options: 您有两种选择:

  1. Use the hash router provided by react-router v4. 使用react-router v4提供的哈希路由器 Routes now will look like this: http://example.com/#/somePage 路线现在看起来像这样: http://example.com/#/somePagehttp://example.com/#/somePage

  2. If you don't like to have a # on the url you have to change the server behaviour. 如果您不想在URL上添加#,则必须更改服务器行为。 This configuration changes for diferents servers. 对于不同的服务器,此配置会发生变化。 In development mode if you are using webpack-dev-server just enable historyApiFallback . 在开发模式下,如果您使用的是webpack-dev-server,则只需启用historyApiFallback In production mode search for how to redirect 403/404 responses using the server you will use. 在生产模式下,搜索如何使用您将使用的服务器重定向403/404响应。

There's a difference between client side and server side routing. 客户端和服务器端路由之间存在差异。 This has been covered in a squillion posts and other places. 这已被广泛的帖子和其他地方所涵盖。 Basically, if your client side react app redirects them to a certain route, that is NOT the same as them manually entering that route in the browser (which contacts the server and tries to get that SPECIFIC route). 基本上,如果您的客户端反应应用程序将它们重定向到某个路由,这与他们在浏览器中手动输入该路由(它与服务器联系并尝试获取该SPECIFIC路由)不同。

So if you have a route in the front end, say: 因此,如果您在前端有路线,请说:

<Route component={Potato} exact path='/potato' />

but in your back end you don't have something which handles requests to said path, then manually going to that URL or refreshing when on that URL will cause your app to poop itself. 但是在你的后端,你没有处理对所述路径的请求的东西,然后手动转到该URL或在该URL上刷新将导致你的应用程序自行停顿。

Make sure you have a catch all route in your back end, something like this: 确保你的后端有一个捕获所有路线,如下所示:

app.get('*', (request, response) => {
    response.sendFile(path.resolve(__dirname, 'index.html'))
});

essentially, a catch all route that just returns your index.html 实质上,捕获只返回index.html的所有路由

Also be sure to look up client side vs server side routing, cos that will cause issues with page refreshing and manually navigating to certain URL's with React Router 另外一定要查看客户端与服务器端路由,这将导致页面刷新问题,并使用React路由器手动导航到某些URL

When deploy my create-react app to heroku, I ran into similar issue, the app works fine until refresh on a subroute. 当我的创建反应应用程序部署到heroku时,我遇到了类似的问题,该应用程序工作正常,直到刷新子路由。 The way I fixed it was adding this file in my root directory. 我修复它的方法是在我的根目录中添加此文件。 Not sure if this will help you on aws. 不确定这是否会对你有所帮助。

static.json

{
  "root": "build/",
  "clean_urls": false,
  "routes": {
    "/**": "index.html"
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM