0

I am rendering a Home component inside a Route so that I can pass state in as a prop to the component.

class App extends React.Component {
    constructor(props){
        super(props)
        this.state = {
            page: 'false'
        };
    }
    render() {
        return (
            <Router>
                <div>
                    <Switch>
                        <Route exact path='/' render={()=><Home page={this.state.page}/>} />
                        <Route exact path='/projects' component={Projects} />
                        <Route render={function(){
                            return <p>Not Found</p>
                        }} />
                    </Switch>
                </div>
            </Router>
        )
    }
}

Inside the Home component, I want to trigger a route change from a function. Because the Component is rendered inside the Route the history prop doesn't get passed in and therefore I cannot trigger a route change like so:

class Home extends React.Component{
    constructor(props){
        super(props);
        this.gotoProjects = this.gotoProjects.bind(this);
    }
    gotoProjects() {
        this.props.history.push('/projects');
    }
    render() {
        return (
            <button onClick={this.gotoProjects.bind(this)}>Projects</button>
        )
    }
}

How can I change routes from a component while still retaining it's props?

UPDATE I've created a History.js using createBrowserHistory

import { createBrowserHistory } from 'history'

export default createBrowserHistory()

And updated App.js to be

import history from '../history';

class App extends React.Component {
    constructor(props){
        super(props)
        this.state = {
            page: 'false'
        };
    }
    render() {
        return (
            <Router>
                <div>
                    <Switch>
                        <Route exact path='/' render={()=><Home history={history} page={this.state.page}/>} />
                        <Route exact path='/projects' component={Projects} />
                        <Route render={function(){
                            return <p>Not Found</p>
                        }} />
                    </Switch>
                </div>
            </Router>
        )
    }
}

So now when I click the button in Home the url goes to /projects but the view is still rendering Home instead of Projects. How do I render Projects after the history.push happens?

Robbie Fikes
  • 409
  • 4
  • 15
  • I suppose this is the answer that you need https://stackoverflow.com/questions/44127739/programatically-routing-based-on-a-condition-with-react-router/44128108#44128108 – Shubham Khatri Jul 17 '17 at 08:35
  • I'm not sure how to structure my code properly to use withRouter – Robbie Fikes Jul 17 '17 at 16:35
  • you just need to use withRouter with the component you wanna use history prop with like `export default witRouter(Home);` – Shubham Khatri Jul 17 '17 at 16:37
  • I got a few errors: index_bundle.js:1834 Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object. Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object. Check the render method of `Route`. – Robbie Fikes Jul 17 '17 at 16:43
  • what are the few error – Shubham Khatri Jul 17 '17 at 16:43
  • "The error is located at: in Route (created by App) in Switch (created by App) in div (created by App) in Router (created by BrowserRouter) in BrowserRouter (created by App) in App" – Robbie Fikes Jul 17 '17 at 16:45
  • instead of creating a custom history and passing it to Home component, just wrap Home component with withRouter HOC and it should be fine, Also make sure you export Home and Projects component and import them properly – Shubham Khatri Jul 17 '17 at 18:09

0 Answers0