Активный маршрут React Router v4 NavLink

Я пытаюсь перенести свой проект с версии 3 react-router на версию 4 того, что сейчас называется react-router-dom. Теперь проблемы возникают, когда у меня есть компонент MenuBar, который полностью отделен от логики маршрутизации (как и следовало ожидать), потому что он будет показывать одни и те же ссылки, каким бы ни был текущий путь. Теперь все это прекрасно работало с v3, но теперь, когда я использую NavLink, который имеет то же свойство activeClassName, активный маршрут не обновляется на панели навигации, а только при обновлении. Это кажется немного глупым, поэтому должен быть способ обойти это.

export default @inject('ui') @observer class App extends Component {
  render() {
    return (
      <Router>
        <div className={ styles.wrapper }>
          <Sidebar />
          <main className={ `${styles.main} ${!this.props.ui.menuOpen && styles.closed}` }>
            <Route exact path="/" component={ HomePage } />
            <Route path="/signup" component={ SignUpPage } />
            <Route path="/login" component={ LoginPage } />
            <Route path="/about" component={ AboutPage } />
          </main>
          <footer className="site-footer"></footer>
        </div>
      </Router>
    );
  }
}

Выше приведена логика моего основного приложения, и, как вы можете видеть, маршруты вложены друг в друга, но сам маршрутизатор охватывает весь компонент.

Что нужно добавить, чтобы они снова заработали? (Они работают правильно при обновлении страницы)


person Dániel Emőd Kovács    schedule 12.03.2017    source источник


Ответы (1)


Судя по тому, как вы используете декоратор @observer, вы используете mobx-react. Что нужно понимать о observer, так это то, что он реализует shouldComponentUpdate для оптимизации производительности рендеринга. Этот вызов sCU будет смотреть на текущий и следующий реквизиты, и если нет разницы, он не будет повторно рендериться. Это проблема, потому что по умолчанию React Router использует контекст для передачи данных и полагается на повторную визуализацию элементов для получения обновленных значений, но sCU observer не имеет возможности обнаруживать изменения контекста.

Обойти это можно, передав объект location в качестве реквизита компоненту, обернутому observer. Затем, когда местоположение изменится, shouldComponentUpdate observer обнаружит разницу и перерендерится.

Вы можете увидеть руководство по заблокированным обновлениям для получения дополнительной информации.

person Paul S    schedule 13.03.2017
comment
Спасибо за ответ. Я действительно подозревал MobX, потому что на данный момент к нему подключено только меню навигации. Я также рассматривал возможность передачи местоположения в качестве реквизита, но решил, что должен быть более элегантный способ сделать это, потому что таким образом мне нужно будет сделать это с каждым компонентом, который должен обновляться с помощью маршрутов и сохранять изменения. - person Dániel Emőd Kovács; 14.03.2017
comment
Еще раз спасибо за ответ, поскольку вы указали мне правильное направление. В конце концов я удалил логику observer из большинства своих компонентов, поскольку они на самом деле не нуждались в ней, и это освободило компоненты от изменения исключительно тогда, когда MobX намеревается это сделать. - person Dániel Emőd Kovács; 14.03.2017