2

I have a NavBar with three links. If I click on a link, the URL updates and I navigate to /categories/categoryID. The first time I click a link everything works fine. But it only works once. If I click another category (the links in my navbar change the categories) the content will not change. But it will, however, change when I refresh the browser.

  1. I click on the Link in the NavBar
  2. The url changes correctly
  3. the component does not re-render
  4. If I refresh the browser the correct content is loaded

There seems to be a disconnect between the URL and the re-rendering of components.

Question: What causes the disconnect?

I have the suspicion that the cause of this behaviour is my implementation of react router (v4).

ReactDOM.render(
    <Provider store={store}>
        <BrowserRouter>
        <div>
            <Header />
            <Switch>
                <Route path="/categories/index/:uuid/" component={CategoryIndex} />
                <Route path="/user/signup" component={SignUpForm} />
                <Route path="/user/login" component={LoginForm} />
                <Route path="/home/" component={IndexPage} />
            <Route/> 
            </Switch>
        </div>
    </BrowserRouter>
    </Provider>
    , document.getElementById('root'));
registerServiceWorker();

The component that does not re-render looks like this:

class PostList extends Component {

    componentDidMount() {
        const { uuid } = this.props.match.params;
        this.props.fetchCategoriePosts(uuid);

    }

    renderPostList() {
        const { category } = this.props;
        if (category) {
            return (
                _.map(category, post => {
                    return(
                        <li className="list-group-item" key={post.uuid}>
                        <div>Hallo</div>
                        <Link to="/">{post.title}</Link>
                        </li>
                    )
            }));
        }
    }

    render() {
        return (
            <div className="container">
                <ul className="list-goup">
                    {this.renderPostList()}
                </ul>
            </div>
        );
    }
}

function mapStateToProps({ category }) {
    return {category}
}

export default connect(mapStateToProps, {fetchCategoriePosts}) (PostList);

Can someone help?

Icepickle
  • 12,014
  • 3
  • 29
  • 43
Xen_mar
  • 4,549
  • 4
  • 24
  • 40
  • how are you changing the url? – Eric Hasselbring Jan 17 '18 at 16:57
  • by using the Link Component from react-router-dom. – Xen_mar Jan 17 '18 at 16:57
  • Any chance you could provide a [mcve] as well, this will keep us guessing ;) Do you have any warnings or errors in your console? – Icepickle Jan 17 '18 at 17:02
  • Firstly `renderPostList` isn't binded and secondly you should check this https://stackoverflow.com/questions/44356360/react-router-work-on-reload-but-not-when-clicking-on-a-link/44356956#44356956 – Shubham Khatri Jan 17 '18 at 17:03
  • 1
    I don't even see `PostList` in your router, if the parent is not mounting or unmounting nor receiving new props/state, its not going to render anything new – Eric Hasselbring Jan 17 '18 at 17:07
  • @EricHasselbring thanks for your answer ... yes, its a little missleading, but I just changed the import name to CategoryIndex. ShubhamKhatri ... is there any reason my renderPostList method should be bound to this? – Xen_mar Jan 17 '18 at 17:33
  • Without seeing all the code it's hard to pin point the issue but Browser Router is not getting the url change. Whatever Link that is being clicked does not have the proper context to change Browser Routers history – Eric Hasselbring Jan 17 '18 at 17:48

2 Answers2

4

Well it appears to be a React lifecycle issue. I assume that you want your component to update and not re-render on URL change.

componentWillUpdate(nextProps) {
  const { uuid } = nextProps.match.params;
  if (uuid !== this.props.params.match.uuid) {
    this.props.fetchCategoriePosts(uuid);
 }
}

(You can also do it in your saga if you listen the event LOCATION_CHANGE)

soupette
  • 1,130
  • 9
  • 11
1

Have you tried wrapping your export with withRouter from react-router-dom? Redux kind of hijacks the lifecycle methods sometimes when used in conjunction with React Router. I had a similar issue with my url updating but a blank page showing and had success with something like below:

export default withRouter(connect(mapStateToProps, {fetchCategoriePosts}) (PostList));
Shirley
  • 282
  • 1
  • 6