Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Page is not rendering after history.push('/path') #822

Open
alexandre-reis opened this issue Jul 21, 2020 · 13 comments
Open

Page is not rendering after history.push('/path') #822

alexandre-reis opened this issue Jul 21, 2020 · 13 comments

Comments

@alexandre-reis
Copy link

alexandre-reis commented Jul 21, 2020

Hi,

I have a problem using history v. 5 with react-router-dom. When I call function history.push('/cart') it sends me to the correct page, but it doesn't show the content.

If I use history version: "4.10.1", it works perfectly.

Am I doing something wrong ?

This is my history.js file

import { createBrowserHistory } from 'history';
const history = createBrowserHistory();
export default history;

And this is my app.js

import React from 'react';
// import { Router } from 'react-router-dom';
import { Router } from 'react-router';
import { Provider } from 'react-redux';
import { ToastContainer } from 'react-toastify';
import store from './store/index';
import history from './services/history';

import Routes from './routes';
import GlobalStyle from './styles/global';
import Header from './components/Header';

function App() {
	return (
		<Provider store={store}>
			<Router history={history} >
				<Header />
				<Routes />
				<GlobalStyle />
				<ToastContainer autoClose={3000} />
			</Router>
		</Provider>
	);
}

export default App;
@alexandre-reis alexandre-reis changed the title Page is not rendering after history.push('/content') Page is not rendering after history.push('/path') Jul 21, 2020
@ritch
Copy link

ritch commented Jul 21, 2020

I'm running into the same. Here's a self contained example: https://codesandbox.io/embed/crazy-dirac-04nil?fontsize=14&hidenavigation=1&theme=dark

import React from 'react'
import {Router} from 'react-router'
import {Route} from 'react-router-dom'
import {createBrowserHistory} from 'history'

const myHistory = createBrowserHistory()

export default function App() {
  return (
    <Router history={myHistory}>
      <Route
        path="/"
        exact={true}
        render={() => <h1 onClick={() => myHistory.push('/todos')}>Home</h1>}
      />
      <Route path="/todos" exact={true} render={() => <h1>Todos</h1>} />
    </Router>
  )
}

Downgrading this example to [email protected] fixes the issue.

@mattfranciswork0
Copy link

I have the same

I'm running into the same. Here's a self contained example: https://codesandbox.io/embed/crazy-dirac-04nil?fontsize=14&hidenavigation=1&theme=dark

import React from 'react'
import {Router} from 'react-router'
import {Route} from 'react-router-dom'
import {createBrowserHistory} from 'history'

const myHistory = createBrowserHistory()

export default function App() {
  return (
    <Router history={myHistory}>
      <Route
        path="/"
        exact={true}
        render={() => <h1 onClick={() => myHistory.push('/todos')}>Home</h1>}
      />
      <Route path="/todos" exact={true} render={() => <h1>Todos</h1>} />
    </Router>
  )
}

Downgrading this example to [email protected] fixes the issue.

You made my entire day :)

@tavareshenrique
Copy link

I have the same, it only works with me if I downgrade to the [email protected] version, if I upgrade to [email protected], the problem reported here will occur and I don’t know how to fix it to use this new version.

@thomasmi
Copy link

thomasmi commented Jul 23, 2020

I am seeing the same issue with v5 using

<Redirect exact from='/' to='/home' />

when I rolled back to [email protected] it works as expected.

@keyvan-m-sadeghi
Copy link

Same problem!

@dominguesgm
Copy link

dominguesgm commented Jul 31, 2020

Writing this here to document what I found in more detail, not sure if it is redundant or not. I ran into this issue and tried to do a bit of debugging inside the react-router source.

It seems that with [email protected], the history.push and history.replace methods create a wrapper around the usual location object and store the type of action there.

For example,

context.location = {
  pathname,
  search,
  hash,
  state,
  key,
}

Becomes

context.location = {
  action: 'REPLACE',
  location: {
    pathname,
    search,
    hash,
    state,
    key,
  }
}

(found from logging the context in react-router's Switch implementation to console)

Since the [email protected]'s Switch tries to find pathname in context.location, it won't find it because it's now in context.location.location.

I assume this is being tackled in react-router v6, and I don't know if it makes sense for this stage to update v5 to play nicely with this breaking change on history, but if it does I wouldn't mind taking a shot at it.

@StringEpsilon
Copy link

FYI, I posted a more detailed overview of all the breaking changes I could find in #811.

@dominguesgm
Copy link

@StringEpsilon Thanks for the list, looks like important info for users. I may be missing something but is the change I mentioned listed there already? In case it isn't, I think it would be a good addition, because it breaks a pretty common use-case.

@StringEpsilon
Copy link

It's the history.listen() change. You can see more details on most entries in the gist.

@mayur-padshala
Copy link

With history 5.x.x, Fails when using

<Router history={history}>
    ...
</Router>

Rendering works nicely when using BrowserRouter.

<BrowserRouter>
    ...
</BrowserRouter>

@StringEpsilon
Copy link

StringEpsilon commented Oct 16, 2020

@mayur-novus That's because using <BrowserRouter/> will pull in and use history@4, as it's a direct dependency of react-router, unless your bundler swaps that out explicitly.

@ruvaleev
Copy link

ruvaleev commented Jan 9, 2021

Writing this here to document what I found in more detail, not sure if it is redundant or not. I ran into this issue and tried to do a bit of debugging inside the react-router source.

It seems that with [email protected], the history.push and history.replace methods create a wrapper around the usual location object and store the type of action there.

For example,

context.location = {
  pathname,
  search,
  hash,
  state,
  key,
}

Becomes

context.location = {
  action: 'REPLACE',
  location: {
    pathname,
    search,
    hash,
    state,
    key,
  }
}

(found from logging the context in react-router's Switch implementation to console)

Since the [email protected]'s Switch tries to find pathname in context.location, it won't find it because it's now in context.location.location.

I assume this is being tackled in react-router v6, and I don't know if it makes sense for this stage to update v5 to play nicely with this breaking change on history, but if it does I wouldn't mind taking a shot at it.

Thank you so much! I was downgrade my 'hisory' from 5.0.0 to 4.1.0 as you mentioned, and now everything works properly )

@jvnlwn
Copy link

jvnlwn commented Oct 26, 2021

Alternatively, here's a solution that does not require downgrading history. Though, assuming react-router v6 solves the issue and is released soon, this solution will be short-lived.

Under <BrowserRouter />, wrap your <Route />s with a component that can handle a CustomEvent, executing a specified navigation method of history provided by the useHistory hook. From outside of your component tree, trigger the CustomEvent.

Here's an example:

// polyfill CustomEvent
import CustomEvent from "custom-event"
import { useEffect } from "react"
import { render } from "react-dom"
import { useHistory } from "react-router-dom"

// Dispatch a history event.
const dispatchHistoryEvent = (action, route, state) => {
  const event = new CustomEvent("history", {
    detail: {
      action,
      route,
      state
    }
  })
  document.dispatchEvent(event)
}

// Execute a history event.
const handleHistoryEvent = (history, event) => {
  const { action, route, state } = event.detail
  history[action](route, state)
}

// Hook up history event listener that will execute history events.
const useHistoryEvent = () => {
  const history = useHistory()

  useEffect(() => {
    const handler = e => handleHistoryEvent(history, e)
    document.addEventListener("history", handler)
    return () => document.removeEventListener("history", handler)
  }, [])
}

const App = ()=> {
  useHistoryEvent()
  // ...
}

render(
  <BrowserRouter>
    <App>
      {/* routes */}
    </App>
  </BrowserRouter>,
  document.getElementById("root")
)

// somewhere outside of component tree
dispatchHistoryEvent("push", "/home/", {/* optional state */})

Note that this works for all history navigation methods, though is not namespaced well for the history.go method. My use case is only for push, replace, back, forward.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests