6

I am doing something like:

<Router history={browserHistory}>{routes}</Router>

When I do above whenever URL in address bar changes call is going to server but this is not what I want, I want first time page to load from server but after that whenever route change component should load in client side only. Am I missing something here?

In client side I am doing something like :

ReactDOM.render(
    <Provider store={app.store}>
        <Router history={browserHistory}>{routes}</Router>
    </Provider>,
    document.getElementById("app")
);

and my routes look like:

const routes = (
    <Route path="/" component={DJSAppContainer}>
        <Route path="page" component={DJSPage}>
            <Route path="/page/:pageName" component={PageContainer} />
        </Route>
    </Route>
);

Now whenever I do location.href = "/page/xyz" it goes to server and load the content.

Guilherme Samuel
  • 459
  • 6
  • 11
Abhinav SInghvi
  • 391
  • 1
  • 4
  • 13
  • 1
    Whenever I have this issue, it means that my client bundle.js could not be created or it's not working. Check if there are any errors in the piece of the client code that is not shared with the server (usually client initiation, history, DOM render, store, middleware and such) – takacsmark Feb 25 '16 at 16:08
  • Are you rendering into the dom in your client side code? – Carl Vitullo Feb 25 '16 at 16:16
  • yes I am rendering into the dom in my client side code, I have updated my question. – Abhinav SInghvi Feb 26 '16 at 05:56
  • How did you import and create the browser history ? – TIJ Feb 29 '16 at 09:37
  • I have this problem but only on local during development -- in production it goes away. You might try a production build and see... – Cymen Oct 01 '16 at 17:41

4 Answers4

6

You shouldn't change location.href directly. You should send the new path to React using:

ReactRouter.browserHistory.push(newPath);

If you have anchor tags, you should use the <Link> component mentioned in @ahutch's answer.

James Brierley
  • 4,630
  • 1
  • 20
  • 39
  • Great and straight forward answer! I am on transitioning my legacy server-side app to the client and would like to introduce react-router. Do you think it would be a viable approach to change `location.href` instead of using `a tags` for routing to my legacy parts of the app and react-routers components to do client side routing? – RemEmber Dec 21 '16 at 15:45
  • @RemEmber I don't see why not, but you should ask that as a separate question to get a more detailed answer. – James Brierley Dec 22 '16 at 16:19
2

React router exposes as props the history used in the current views. See their docs for all the props that are injected here.

If you want to redirect from DJSAppContainer or any of the two children views DJSPage or PageContainer you could do it by accessing the history property:

const {history} = this.props;
history.pushState('/path/to/new/state');

If on the other hand you do some fancy stuff and want to redirect from outside the components, try this (taken from react router docs)

// somewhere like a redux/flux action file:
import { browserHistory } from 'react-router'
browserHistory.push('/some/path')

This two approaches assume you are trying to redirect based on some complex logic, not as a consequence of a click event. If you just want to handle click events, try using the <Link/> component of react-router.

It seems that the history property is now deprecated, and seems to be replaced by the router context property as seen in the implementation of the link component. Basically, if you really want your code to be future proof, you should ask for the contextType:

contextTypes: {
     router: object
},

And then use it from the context of the component:

this.context.router.push('/some/path')
Vlad Nicula
  • 3,577
  • 6
  • 32
  • 50
1

Assuming you're using node on the back-end, make sure that you have it set up according to the react-router docs.

// send all requests to index.html so browserHistory in React Router works
app.get('*', function (req, res) {
  res.sendFile(path.join(__dirname, 'index.html'))
})

Also, when you're linking between components and you want to ensure that you are using react-router for the routing instead of the server, make sure to use Link. Hope that answers your question.

ahutch
  • 154
  • 1
  • 5
0

I was having a similar issue, while hashHistory worked without issue browserHistory would always load from the server. I got things working by remembering to call preventDefault(). Here is my function:

handleSubmit: function (e) {
    e.preventDefault();
    var username = this.usernameRef.value;
    this.usernameRef.value = '';
    this.context.router.push(`/profile/${username}/`);
}

handleSubmit is called on a form onSubmit.

bexley
  • 59
  • 8