Ian A. Ian A. - 1 month ago 11
React JSX Question

How do I go to a specific page in React based on a URL param

As an example when entering

http://localhost:3000/ui/?goto=/ui/entity/e2
in the browser I'd like to go to the Entity component e2.

This is my router:

<Route path="/ui/" component={App}>
<IndexRoute component={EntitiesPage} />
<Route component={Entity} path="entity/:id" />
<Route component={NotFound} path="*" />
</Route>


This is the App component:

import React from 'react'

const App = React.createClass( {
render() {
let gotoUrl = this.props.location.query.goto;
if (gotoUrl) {
// go here: gotoUrl;
} else {
return (
<div className="App">
{this.props.children}
</div>
)
}
}
})
export default App


this.context is empty.
this.props has:


  • history

  • location

  • route

  • routeParams (empty)

  • routes



UPDATE:
I've ended up using this:

import React from 'react'
import { withRouter } from 'react-router'

const App = React.createClass( {
componentWillMount() {
let gotoUrl = this.props.location.query.goto;
if (gotoUrl) {
this.props.history.replace(gotoUrl);
}
},

render() {
return (
<div className="App">
{this.props.children}
</div>
);
}
})
export default withRouter(App)

Answer

One thing that might be tripping you up is that render should have no side effects.

A "side effect" is anything that changes what's going on in your app*: updating state, making AJAX calls, or in this case, altering the page location. The render method should only read from the current state of the component, then return a value.

Because you're already using React.createClass, the best way to handle this is by adding a separate method that React handles specially: componentWillMount. I'd recommend you put your "redirect" logic here.

In order to properly change the page location, you'll need access to the browser history object which react-router manipulates. You can import this from the react-router library itself and directly call methods on it:

// At top of file
import { browserHistory } from 'react-router'

// Then, in your component:
componentWillMount() {
  let gotoUrl = this.props.location.query.goto;
    if (gotoUrl) {
        // NOTE: this may have security implications; see below
        browserHistory.push(gotoUrl);
    }
}

Source: documentation.

I'd suggest that, instead of using query.goto, you instead select a parameter that can be easily validated, such as the entity ID itself (a simple regex can make sure it's valid). Otherwise, an unscrupulous user might send a link to another user and cause them to access a page that they didn't mean to.

*Note: there are stricter definitions of "side effect" out there, but this one is pretty useful for React development.