Как передать компонент через рутер в ReactJS?

327
16 марта 2017, 22:40

В приложении есть зарегестрирвоанные и незарегестрированные пользователи. Соответственно для тех и для других будут разные хедеры на сайте(хедеры лежат в отдельных файлах и экспортируются в страницы сайта).С помощью хука onEnter в рутере реакта я реализую метод проверки наличия токена в текущей сессии у пользователя.Если токен есть токен есть, пользователь может зайти по определенным рутам, если нет, то его с помощью replace редиректит на страницу с формой входа. Все работает, однако осталась одна загвоздка- хедер. Можно реализовать проверку в каждом компоненте и в зависимости от нее посдтавлять гостевой,или пользовательский хедер, но я не думаю,что это хорошее решение. Думаю лучшим способом было бы проверять залогинен пользователь,или нет и подкидывать тот или иной хедер в страницу на уровне рутера. К сожалению я не нашел подходящего решения в сети. Подскажите пожалуйста как лучше поступитьв такой ситуации?

Код рутера и onEnter(Сейчас я сделал 2 главные страницы и прпоисал в них нужные хедеры.Соответственно, если получится подбрасывать нужный хедер останется одна главная страница):

const App = React.createClass({
    render: function() {
        return (
            <div className="content">
                <div className="app-container">
                    {this.props.children}
                </div>
            </div>
        )
    }
});
function authCheck(nextState,replace) {
        const token = window.localStorage.getItem(config.token);
        if (token != undefined) {
        } else {
          replace('/login');
        }
}
render((<Router history={hashHistory}>
        <Route path="/" component={App}>
              <IndexRoute component={MainPageGuest}/>
              <Route path="dash" component={MainPageUser} onEnter={authCheck}/>
              <Route path="user" component={UserPage} onEnter={authCheck}/>
        </Route>
    </Router>
), document.getElementById('application'));
Answer 1

Можно сделать так, чтобы не вставлять код в каждый компонент:

const App = React.createClass({
  render: function() {
    return (
        <div className="content">
            <div className="app-container">
                {'залогенен' ? <HeaderWithAuth /> : <HeaderNotAuth />}
                {this.props.children}
            </div>
        </div>
    )
  }
});

Теперь header будет находиться рядом с компонентом.

Answer 2

Можно вместо component в роутере передать св-во components, среди которых будет указан необходимый для таких маршрутов хедер. Такой подход позволит не только учитывать авторизацию, но и, например, роли. Проверка так же остается в onEnter, только вот что именно рендерить определяется на уровне роутера.

<Route component={App}>
  <Route path="guest" components={{page: MainPageGuest, header: GuestHeader}}/>
  <Route path="users" components={{page: UserPage, header: UserHeader}}>
    <Route path="users/:id" component={Profile}/>
  </Route>
  <Route path="admin" components={{page: AdminPage, header: AdminHeader}}>
    <Route path="admins/panel" component={Panel}/>
  </Route>
</Route>
class App extends React.Component {
  render () {
    const { page, header } = this.props;
    return (
      <div>
        <div className="header">
          {header}
        </div>
        <div className="page">
          {page}
        </div>
      </div>
    )
  }
}
READ ALSO
Оптимизация JavaScript кода

Оптимизация JavaScript кода

Все изумительно работает , но можно как то оптимизировать подобный код ? Знаний JS не достаточно , а таких скриптов штук 20 на странице( И кажутся...

351
Автоматическая смена цвета у блока

Автоматическая смена цвета у блока

Мне очень нравится фишка с сайта Артемия Лебедева, где в шапке у них логотипТак вот этот логотип со временем медленно меняет свой цвет, а при...

443
Кириллица в Unicode

Кириллица в Unicode

Написал функцию, которая шифрует текст по методу ЦезаряРаботает она по методу превращения каждого символа в числовое значение Юникода:

347