Реагировать на маршрут с постоянным ящиком

Допустим, у меня есть приложение React (с React Router 4) со следующими компонентами и маршрутами:

  • App (/)
    • Toolbar - A fixed toolbar
      • NavButton - A button whose appearance and behavior depends on the current route (see below)
    • MainMenu - временный ящик, который выдвигается сбоку для навигации между маршрутами верхнего уровня.
    • Admin (/admin)
      • Sidenav - A navigation drawer that is open all of the time on large screens and can be toggled on small screens. Clicking on items in the Sidenav navigates to different sub-routes under /admin
      • Content (/admin/<xyz>)
    • Public (/public)
      • Content

Поведение NavButton должно быть следующим:

  • On a large screen:
    • it should always be a hamburger icon that opens the MainMenu.
  • On a small screen: (except for the first condition, this is similar to the experience on the Gmail mobile app)
    • if there is no Sidenav, it should display a hamburger icon that opens the MainMenu.
    • если Sidenav закрыт, должен отображаться значок "Назад", открывающий Sidenav.
    • если Sidenav открыт, на нем должен отображаться значок гамбургера, открывающий MainMenu.

Маршруты /admin и /public являются лишь примерами. Есть много других, некоторые из которых имеют Sidenav, а некоторые нет.

У меня такой вопрос: как с помощью React можно управлять состоянием пользовательского интерфейса и соединять вместе все компоненты и маршруты? Кажется, что App должен нести ответственность за отслеживание того, открыта ли боковая навигация, чтобы он мог передавать эту информацию Toolbar и другим, но также кажется, что App не должен отвечать за управление тем, потенциальных детей имеют или не имеют Sidenavs. Кроме того, как могут быть переданы реквизиты от App какому-то дочернему элементу, если между ними есть Route?

Примечание: я новичок в React и, конечно же, не связан с вышеописанной структурой компонентов; это просто для иллюстрации.


person ethan.roday    schedule 23.06.2017    source источник
comment
К слову, я знаю, что могу просто превратить NavButton и Sidenav в «умные» компоненты, подключив их к хранилищу redux и просто реагируя на изменения в state.isScreenBig и state.isSidenavActive. Но это кажется неряшливым. Кроме того, он не распространяется на случай, когда state.isSidenavActive === true и пользователь переходит от /admin к /public. Кто отвечает за возврат state.isSidenavActive к false?   -  person ethan.roday    schedule 23.06.2017


Ответы (1)


Такое чувство, что приложение должно нести ответственность за отслеживание того, открыта ли боковая навигация.

Правда. Дочерние компоненты всегда должны быть презентационными (чистыми / тупыми) компонентами.

Приложение не должно отвечать за управление тем, у кого из его потенциальных детей есть или нет Sidenav.

Я бы не назвал это «ответственным». Это просто сохранение состояния приложения. Пользователь берет на себя ответственность, нажимая кнопку гамбургера.

как могут быть переданы реквизиты от приложения к какому-то потомку, если между ними есть маршрут?

Почему нет? Вы можете использовать render вместо component. Например:

let Parent = (props)=> {
 <Route 
   path="/pizza" 
   render={()=> <Pizza topping={props.topping} />}  />
}
person Moe    schedule 25.06.2017