Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Router 4 triggering full page reload

React Router 4 is running on top of Rails and React, but following a <Link /> element triggers a GET request in my server and a full page reload in my development environment.

Here are the current versions I'm running:

"@rails/webpacker": "^3.0.2",
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-router-dom": "^4.2.2",
"clean-webpack-plugin": "^0.1.17",
"webpack-dev-server": "^2.9.5",
"webpack-merge": "^4.1.1"

I'm using the foreman gem, which runs the rails server and webpack-dev-server on localhost:5000.

What I've tried:

  • Adding historyApiFallback to my webpack-dev-server CLI
  • Using either <Link /> and <NavLink />
  • Adding a trailing / to my links; <Link path='/sign-in/' component={Register} />
  • Rendering just <App /> at the highest level component, and adding <BrowserRouter /> and all routing/switching to <App />
  • I've tried using exact path, strict path, and just path

I'm curious if it's something with my webpack config... I can post that as well if necessary. It just seems like this is all set up right but something else funky is going on.

What is working: - I can switch between components, even though my rails routes in routes.rb has a catch-all: get '*path', to: 'pages#index'

Here is my highest level component, index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router } from 'react-router-dom';

import Main from '../react/src/components/Main';

document.addEventListener('DOMContentLoaded', () => {
    ReactDOM.render(
        <Router>
            <Main />
        </Router>,
        document.getElementById('app')
    );
});

Here is main.js:

import React from 'react';
import { Route, Switch, } from 'react-router-dom';
import Dashboard from './Dashboard';
import FormContainer from './FormContainer';

const Main = props => {
    return (
        <main>
            <Switch>
                <Route path="/sign-in/" component={FormContainer} />
                <Route path="/" component={Dashboard} />
            </Switch>
        </main>
    );
};

export default Main;

An example of a component that is rendered, Dashboard.js:

import React from 'react';
import { Link } from 'react-router-dom';

const Dashboard = props => {
    return (
        <div>
            <h2>Dashboard</h2>
            <Link to="/sign-in/">Sign In</Link>
        </div>
    );
};

export default Dashboard;

The empty controller responsible for my root page:

class PagesController < ApplicationController
end

Also my routes.rb:

Rails.application.routes.draw do
  root "pages#index"
  get '*path', to: 'pages#index'
end

I've gone through multiple tutorials and I'm fairly certain that this is structured correctly... I think I'm mainly looking for any hints as to what may be interfering with React Router, outside of the library, i.e. webpack, running on localhost, etc.

like image 738
Drew André Avatar asked Nov 19 '22 00:11

Drew André


1 Answers

I was able to fix this issue by renaming a tag of <main> that my application.html.erb's <%= yield %> tag was wrapped in... I don't quite understand why wrapping <%= yield %> in a tag specifically called <main> causes a page reload/disables client-side rendering, but in my case, it did!

like image 69
Drew André Avatar answered Dec 19 '22 16:12

Drew André