React Router how to setup transition on parent element

Gasim Source

I have a simple router configuration:

<Router history={browserHistory}>
    <Route lang="en" path="en" component={App}>
        <Route path="*" component={PageFactory} />
    </Route>
    <Redirect from="*" to="/en/*" />
</Router>

and main App component has the following:

<div className="app">
    <Home />
    <Sidebar {...sidebarProps}>
        {this.props.children}
    </Sidebar>
</div>

So, the Home component always opens when you open the react application. When I click a link in Home component (e.g /en/pages/about-page), the contents of the page gets loaded to Sidebar component and Sidebar gets a prop isOpen (That's what ...sidebarProps is for). Everything works fine. When I click a link Sidebar opens, and contents show with overlay etc. However, transitions do not animate. Here is my CSS:

.sidebar {
    position: fixed;
    left: 0px;
    top: 0px;
    width: 100%;
    height: 100%;
    z-index: 200;
    visibility: hidden;
    background: rgba(0, 0, 0, 0.8);
    overflow: scroll;
    @include transition(visibility 0s linear 0.3s);
    &.is-open {
        visibility: visible;
        @include transition-delay(0s);
        .sidebar-content {
            @include transform(translateX(0));
        }
    }
}

The isOpen prop in Sidebar adds class is-open to root element of Sidebar component. Here is Sidebar component for reference:

const Sidebar = props =>
    <aside className={`sidebar ${props.isOpen ? ' is-open' : ''}`}>
        <SidebarContent>{props.children}</SidebarContent>
    </aside>
;

For testing to see whether it is a React problem, I added a button like the following to my App component:

constructor(props) {
    super(props);
    this.enableSidebar = this.enableSidebar.bind(this);
    this.state = { isOpen: false };
}

enableSidebar() {
    this.setState({ isOpen: true });
}

render() {
    const sidebarProps = { isOpen: this.state.isOpen };
    return (
        <div className="app">
            <button onClick={this.enableSidebar}>Enable Sidebar</button>
            <Home />
            <Sidebar {...sidebarProps}>{this.props.children></Sidebar>
        </div>
    );
}

And when I click the button, sidebar opens smoothly. It is React Router that completely reloads the page on every request, making every page be a static page instead of creating a dynamic application.

How can I change this behavior? How can I make React Router to not reload all components on route change? I am thinking that maybe the structure that I have is problematic. If you also think it is, can you suggest me a solution?

cssreactjsreact-router

Answers

answered 1 year ago Gasim #1

I have found the problem. I had to use React Router Link component instead of HTML anchor element. So instead of using:

<a href="/en/pages/about-page">About</a>

I have to use:

<Link to="/en/pages/about-page">About</Link>

comments powered by Disqus