3

I'm using MobX @observer and @withRouter (react-router-v4) wrap page component like this

@withRouter
@inject('stores')
@observer
class Page extends Component {
  render() {
    return (
      <div>
        <NavBar />
        <Header title={this.props.stores.UIStore.title} />
        <Switch>
          <Route exact path="/" component={HomePage} />
          <Route exact path="/about" component={AboutPage} />
          <Route component={NotFound} />
        </Switch>
      </div>
    )
  }

Problem
When route location change the NavBar and Header component alway re-render with same props (no any state update). react-perf show many wasted render (no props/state update) when route change.

NavBar include Link and some MobX state (NavBar wrap with @observer+@inject only)
Header is just a stateless component.

Page component require @withRouter cause of @observer (MobX) break react-router (https://github.com/mobxjs/mobx-react/issues/210)

How to prevent NavBar and Header re-render from route location change? Allow re-render only when mobx state update.

jeanzuck
  • 726
  • 1
  • 7
  • 17
  • Am I missing something, or it is an expected behaviour? On route change your ```Page``` component re-renders, and all of its children also will be rerendered – Limbo Apr 21 '18 at 15:10

1 Answers1

2

I know this is quite old, but that’s how I solved the same problem in my project:

  1. Don’t use withRouter and observer together. Observer implementation of shouldComponentUpdate will return true if location or match objects change.
  2. When you just need a history or location objects use routerStore from mobx-react-router (https://github.com/alisd23/mobx-react-router)
  3. When you need match (usually because of params), make a non-observer component that uses withRouter and pass necessary params to lower levels of hierarchy.
  • Thank you Nikita! This saved me a LOT of time. Followed the 1st and the 2nd steps and fixed the issue I was facing. I haven't checked the 3rd step, though. – Igor Soloydenko Feb 03 '21 at 22:12