Changing URL onClick in ReactJS
Asked Answered
P

1

4

In my project I have a TabComponent which displays 3 tabs: home, popular, all.

Now, I am using context of react to maintain:

  1. activetab which stores current tab.
  2. toggleTab method which changes activetab using setState.

TabComponent

import React, {Component} from 'react'
import Context from '../../provider'
import {Nav, NavItem, NavLink} from 'reactstrap'
import {Redirect} from 'react-router-dom'
import classnames from 'classnames'

export default class TabComponent extends Component {
    render() {
        return (
            <Context.Consumer>
                {context => (
                    <Nav tabs color='primary'>
                        <NavItem>
                            <NavLink
                                className={classnames({ active: context.activeTab === '1' })}
                                onClick={() =>{context.toggleTab('1')}}
                            >
                            Home
                            </NavLink>
                        </NavItem>
                        <NavItem>
                            <NavLink
                                className={classnames({ active: context.activeTab === '2' })}
                                onClick={() => {context.toggleTab('2')}}
                            >
                            Popular
                            </NavLink>
                        </NavItem>
                        <NavItem>
                            <NavLink
                                className={classnames({ active: context.activeTab === '3' })}
                                onClick={() => {context.toggleTab('3')}}
                            >
                            All
                            </NavLink>
                        </NavItem>                
                    </Nav>
                )}
            </Context.Consumer>
        )
    }
}

What I want to achieve is, onClick should also change the URL.

  • For tab 1, the url should be \home\
  • For tab 2, the url should be \popular\
  • For tab 3, the url should be \all\

Using this.props.history in the onClick method is not working with export default withRouter(TabComponent).

<NavLink
    className={classnames({ active: context.activeTab === '1' })}
    onClick={() =>{
        context.toggleTab('1');
        this.props.history('/home/');
    }}
>

Error:

You should not use <Route> or withRouter() outside a <Router>


window.location in onClick:

<NavLink
    className={classnames({ active: context.activeTab === '1' })}
    onClick={() =>{
        context.toggleTab('1');
        window.location = '/home/';
    }}
>

This actually works but the behaviour is not good.

Clicking the tab does the following:

  1. It Changes the content of body using context.toggleTab.
  2. Then it changes the URL using window.location.
  3. Since, the URL changed, the page is getting reloaded.

The problem here is the content is already loaded in the 1st step. Using window.location changes the URL but also re-loads the page which is not required. It there a way to do skip the 3rd step or is that any other method which just changes the URL?

Pipes answered 6/7, 2018 at 8:12 Comment(7)
If you are using react-router , you can use this.props.history(url). Else you can use window.location = url.Swansea
I am unsure on where to write this.props.history(url)!!Pipes
You can either write it in your onClick function or in the toggle function. Both would work i guessSwansea
I am getting error if i do that, I have updated my question.Pipes
That is because TabComponent is not rendered by <Route>. So you can use window.location = url instead of this.props.historySwansea
How do I solve the problem that I stated in the update?Pipes
Let us continue this discussion in chat.Swansea
C
3

Your TabComponent does not have access to the React Router history route prop because it's probably not used as a component given to a Route.

You could use withRouter on your TabComponent to get access to the route props.

class TabComponent extends Component {
    render() {
      // ...
    }
}

export default withRouter(TabComponent);

You also must make sure that you have a Router component at the top of your app.

Example

class App extends Component {
  render() {
    return (
      <BrowserRouter>
        {/* ... */}
      </BrowserRouter>
    );
  }
}
Croteau answered 14/7, 2018 at 11:35 Comment(2)
That did do the trick, I didn't quite understand why we need to have a BrowserRouter at top level?Pipes
@SreekarMouli withRouter uses values from the context supplied by the Router component, so if a component using the withRouter HOC is rendered outside of the Router, it cannot get the proper information it needs.Croteau

© 2022 - 2024 — McMap. All rights reserved.