简体   繁体   中英

Having troubles with react-semantic-ui and router

so heres the sample:

simple menu/header JSX:

<Menu fixed='top' inverted>
    <Container>
        <Menu.Item header>Simple Blog</Menu.Item>

        <Menu.Item name='home' as={Link} to='/'
                   active={this.state.activeItem === 'home'}
                   onClick={this.handleItemClick}>Home</Menu.Item>

        <Menu.Item name='create-p' as={Link} to='/create-post'
                   active={this.state.activeItem === 'create-p'}
                   onClick={this.handleItemClick}>Create post</Menu.Item>
    </Container>
</Menu>

then I have basic index.js:

ReactDOM.render(
<Provider store={createStoreWithMiddleware(reducers)}>

    <BrowserRouter>
        <div>
            <ApplicationMenu/>
            <Container style={{marginTop: '5em'}}>
                <Route exact path="/" component={Posts}/>
                <Route exact path="/home" component={CreatePost}/>
            </Container>
        </div>
    </BrowserRouter>
</Provider>
, document.querySelector('.start'));

It renders and looks fine. When I click one of menu items I can see the URL changing, but no action is taken besides that. Router does not render new component. If I select the changed URL and click enter, it renders the proper one, but it looks like it does not react on url changes provoked by semantic ui component.

For debug purposes I prototyped these menu items just using clean html and css (pure sui, not react one) and it worked.

Did anyone have have similar problems and managed to figure it out?

Thanks for any answer.

This is a common problem to react-router-dom.

React works the way that it rerenders everytime either:

  • the properties of a component change
  • the internal state changes

If you change the URL of the page, you do not trigger a rerender of that component. Therefore, your index.js won't be rerendered.

A simple solution to this problem is to wrap your Component with a withRouter.

So your new index should look like this:

import { withRouter } from 'react-router-dom';

ReactDOM.render(withRouter(
<Provider store={createStoreWithMiddleware(reducers)}>

    <BrowserRouter>
        <div>
            <ApplicationMenu/>
            <Container style={{marginTop: '5em'}}>
                <Route exact path="/" component={Posts}/>
                <Route exact path="/home" component={CreatePost}/>
            </Container>
        </div>
    </BrowserRouter>
</Provider>)
, document.querySelector('.start'));

Now when the URL changes, the higher order component "withRouter" notices it and rerenders the component in it, so your correct component will be rendered.

As documented here: https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/guides/blocked-updates.md

If you want to know more about the problem, read this GitHub issue: https://github.com/ReactTraining/react-router/issues/5037

Your Route path don't match your Item Link to .

Try changing your routes to:

<Switch>
 <Redirect exact path="/" to="/home">
 <Route exact path="/home/" component={Posts}/>
 <Route exact path="/create-post/" component={CreatePost}/>
</Switch>

BTW: Take a look at react-router's <NavLink> to use instead of <Link> for your Navbar items.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM