Alisa F. Kennedy
Alisa F. Kennedy

Reputation: 171

router changed but component does not rerender

I'm using react-router v4 and redux. I have a react-router event like so

//src/App/components/common/Notifications
onCommentClick = (id) => {
    this.props.history.push(`/dashboard/${id}`)
}

It will change the browser url, my route is setup correctly I guess

//src/App/containers/dashboard/user/NotificationDetail
renderUserRoute() {
    return (
      <Switch>
        <Route exact path="/dashboard" component={UserAreaGuarded} />
        <Route exact path="/dashboard/:id" component={NotificationDetail} />
      </Switch>
    )
  }

but the problem is redux doesn't seem to rerender my container component, I need to refresh to get the right content.

I created a repo just to demo this issue https://github.com/thian4/hoc-redux, been stuck for so long for this, couldn't find any clue why it doesn't rerender.

Upvotes: 2

Views: 5490

Answers (1)

hazardous
hazardous

Reputation: 10837

The problem was not with the router, the NotificationDetail component invokes fetchNotification only in componentDidMount. As you are rendering the route components with the Route component prop, the NotificationDetail route component is mounted only once and then merely updated on every re-render.

There are two ways to fix this...

  1. In NotificationDetail, do the fetchNotification stuff in componentDidUpdate instead of componentdidMount, simply rename the method. This approach is better.

  2. Use a stateless component as the value of component prop in dashboard\index.js:

    renderUserRoute() {
      return (
        <Switch>
          <Route exact path="/dashboard" component={UserAreaGuarded} />
          <Route exact 
              path="/dashboard/:id" 
              component={props => <NotificationDetail {...props} />} />
        </Switch>
      )
    }
    

    This will make React-Router render a new route component every time the route changes. Obviously this has performance issues over #1.

Unrelated to this, please add a key={i} on this line in Notification.js to fix the dreaded Each child in an array or iterator should have a unique "key" prop. warning.

Hope this helps.

Upvotes: 1

Related Questions