web-dev-qa-db-fra.com

React-router v4 - ne peut pas obtenir * url *

J'ai commencé à utiliser react-router v4. J'ai un simple <Router> dans mon app.js avec quelques liens de navigation (voir le code ci-dessous). Si je navigue vers localhost/vocabulary, le routeur me redirige vers la bonne page. Cependant, lorsque j'appuie sur reload (F5) par la suite (localhost/vocabulary), tout le contenu disparaît et le rapport de navigateur Cannot GET /vocabulary. Comment est-ce possible? Quelqu'un peut-il me donner un indice sur la façon de résoudre ce problème (recharger la page correctement)?

App.js:

import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter as Router, Route, Link } from 'react-router-dom'
import { Switch, Redirect } from 'react-router'
import Login from './pages/Login'
import Vocabulary from './pages/Vocabulary'

const appContainer = document.getElementById('app')

ReactDOM.render(
  <Router>
    <div>
        <ul>
          <li><Link to="/">Home</Link></li>
          <li><Link to="/vocabulary">Vocabulary</Link></li>
        </ul>
        <Switch>
          <Route exact path="/" component={Login} />
          <Route exact path="/vocabulary" component={Vocabulary} />
        </Switch>
    </div>
  </Router>,
appContainer)
39
exoslav

Je suppose que vous utilisez Webpack. Si tel est le cas, l’ajout de quelques éléments à votre configuration Webpack devrait résoudre le problème. Plus précisément, output.publicPath = '/' et devServer.historyApiFallback = true. Voici un exemple de configuration de webpack ci-dessous qui utilise les deux méthodes ^ et corrige le problème d'actualisation pour moi. Si vous êtes curieux, "pourquoi", ceci aidera.

var path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './app/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'index_bundle.js',
    publicPath: '/'
  },
  module: {
    rules: [
      { test: /\.(js)$/, use: 'babel-loader' },
      { test: /\.css$/, use: [ 'style-loader', 'css-loader' ]}
    ]
  },
  devServer: {
    historyApiFallback: true,
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: 'app/index.html'
    })
  ]
};

J'ai écrit plus à ce sujet ici - Correction de l'erreur "ne peut pas GET/URL" lors de l'actualisation avec React Router (ou comment les routeurs côté client fonctionnent)

113
Tyler McGinnis

Juste pour compléter la réponse de Tyler à ceux qui ont encore du mal à faire ça:

L'ajout du devServer.historyApiFallback: true à la configuration de mon pack Web (sans définir publicPath) corrige les erreurs 404/Cannot-GET que je voyais lors de l'actualisation/le retour/l'avance, mais uniquement pour un seul niveau de route imbriquée. En d’autres termes, "/" et "/ topics" ont bien fonctionné, mais tout ce qui va au-delà (par exemple, "/ topics/tout ce que") a encore lancé un 404 sur rafraîchir/etc.

Je viens de trouver la réponse acceptée ici: Jeton inattendu <erreur dans le composant de routeur de réaction et il a fourni la dernière pièce manquante pour moi. L'ajout du / principal au script de paquetage src dans mon index.html a complètement résolu le problème.

12
Will Ashe

J'avais le même problème, ce qui a été résolu pour moi était la modification de mon fichier package.json, et sous scripts: {

"build": "webpack -d && copy src\\index.html dist\\index.html /y && webpack-dev-server --content-base src --inline --port 3000"

à la fin de mon pack Web build code J'ai ajouté --history-api-fallback Cela semblait également être la solution la plus simple à l'erreur Cannot GET /url.

Remarque: la prochaine fois que vous compilerez après avoir ajouté --history-api-fallback, vous remarquerez dans la sortie une ligne qui ressemble à ceci (avec le fichier d'index utilisé):

Les 404 vont se replier sur /index.html

3
Jared

Si vous utilisez Webpack, vérifiez votre configuration, en partie dans la configuration du serveur, pour l'attribut "ContentBase". Vous pouvez définir par cet exemple:

devServer: {
    ...
    contentBase: path.join(__dirname, '../')
    ...
}
1
Alex

Si vous utilisez Express (pas Webpack), cela a fonctionné pour moi.

app.get('/*', function(req, res) {
  res.sendFile(path.join(__dirname, 'path/to/your/index.html'), function(err) {
    if (err) {
      res.status(500).send(err)
    }
  })
})
0
Marty McGee

Si votre application est hébergée sur un serveur de fichiers statique, vous devez utiliser a au lieu de.

import { HashRouter } from 'react-router-dom'

ReactDOM.render((
  <HashRouter>
    <App />
  </HashRouter>
), holder)

https://github.com/ReactTraining/react-router/blob/v4.1.1/FAQ.md#why-doesnt-my-application-render-after-refreshing

0
jsina

J'avais le même problème, mais j'ai été corrigé après avoir arrêté et relancé Webpack.

0
Carlos Aleman

J'ai aussi eu du succès avec cela en ajoutant ... historyApiFallback: true

devServer: {
        contentBase: path.join(__dirname, "public"),
        watchContentBase: true,
        publicPath: "/dist/",
        historyApiFallback: true
    }
0
SheldonO'Reilly