Я думаю, что ваш лучший вариант, вероятно, использовать либо скрытые state
, либо строки запроса (для постоянных ссылок), либо и то, и другое, особенно если модальная мода (например, мода входа) может отображаться на любой странице. На всякий случай, когда вы не знаете, React Router предоставляет часть истории API state
, позволяющую хранить данные в истории пользователя, которые на самом деле не видны в URL-адресе.
Вот набор маршрутов, которые я имею в виду; вы можете прыгать straight into the working example on JSBin, если хотите. Вы также можете просмотреть полученный в результате пример app in its own window, чтобы вы могли видеть изменение URL-адресов (он использует стратегию размещения хэша для совместимости с JSBin) и чтобы убедиться, что обновление работает так, как вы ожидали.
const router = (
<Router>
<Route component={LoginRedirect}>
<Route component={LocationDisplay}>
<Route path="/" component={ModalCheck}>
<Route path="/login" component={makeComponent("login")} />
<Route path="/one" component={makeComponent("one")} />
<Route path="/two" component={makeComponent("two")} />
<Route path="/users" component={makeComponent("users")}>
<Route path=":userId" component={UserProfileComponent} />
</Route>
</Route>
</Route>
</Route>
</Router>
);
Давайте исследовать эти маршруты и их компоненты.
Прежде всего, makeComponent
- это всего лишь метод, который берет строку и создает компонент React, который отображает эту строку как заголовок, а затем все его дочерние элементы; это просто быстрый способ создания компонентов.
LoginRedirect
является компонентом с одной целью: проверить, если путь /login
или если есть строка ?login
запроса на пути тока. Если любое из этих значений истинно, и текущее состояние не содержит ключа login
, оно устанавливает login
ключ в состоянии true
. Маршрут используется, если соответствует любому дочернему маршруту (то есть компонент всегда отображается).
class LoginRedirect extends React.Component {
componentWillMount() {
this.handleLoginRedirect(this.props);
}
componentWillReceiveProps(nextProps) {
this.handleLoginRedirect(nextProps);
}
handleLoginRedirect(props) {
const { location } = props;
const state = location.state || {};
const onLoginRoute = location.query.login || location.pathname === "/login";
const needsStateChange = onLoginRoute && !state.login;
if (needsStateChange) {
// we hit a URL with ?login in it
// replace state with the same URL but login modal state
props.history.setState({login: true});
}
}
render() {
return React.Children.only(this.props.children);
}
}
Если вы не хотите использовать строки запроса для показа входа модальности, вы, конечно, можете изменить этот компонент в соответствии с вашими потребностями.
Далее LocationDisplay
, но это всего лишь компонент, который я создал для демонстрации JSBin, которая отображает информацию о текущем пути, состоянии и запросе, а также отображает набор ссылок, демонстрирующих функциональность приложения.
Состояние входа в систему важна для следующего компонента: ModalCheck
. Этот компонент отвечает за проверку текущего состояния для login
(или profile
или, возможно, любых других) ключей и, при необходимости, отображения соответствующего модального кода.(Демо JSBin реализует супер простую модальность, ваш, конечно, будет лучше. :) Это также показывает статус модальных проверок в текстовом виде на главной странице.)
class ModalCheck extends React.Component {
render() {
const location = this.props.location;
const state = location.state || {};
const showingLoginModal = state.login === true;
const showingProfileMoal = state.profile === true;
const loginModal = showingLoginModal && <Modal location={location} stateKey="login"><LoginModal /></Modal>;
const profileModal = showingProfileMoal && <Modal location={location} stateKey="profile"><ProfileModal /></Modal>;
return (
<div style={containerStyle}>
<strong>Modal state:</strong>
<ul>
<li>Login modal: {showingLoginModal ? "Yes" : "No"}</li>
<li>Profile modal: {showingProfileMoal ? "Yes" : "No"}</li>
</ul>
{loginModal}
{profileModal}
{this.props.children}
</div>
)
}
}
Все остальное является довольно стандартным React Router вещи. Единственное, что следует обратить внимание, это Link
s внутри LocationDisplay
, которые показывают, как вы можете ссылаться на различные места в вашем приложении, показывая модальности при определенных обстоятельствах.
Прежде всего, вы можете, конечно, ссылки (и постоянная ссылка) на любую страницу с просьбой показать логин модальность с помощью login
ключа в строке запроса:
<Link to="/one" query={{login: 1}}>/one?login</Link>
<Link to="/two" query={{login: 1}}>/two?login</Link>
Вы также можете, конечно, , ссылка на адрес /login
.
Далее, обратите внимание, что вы можете явно указать состояние, чтобы модальное отображение, и это будет не изменить URL. Тем не менее, он будет сохраняться в истории, поэтому назад/вперед можно использовать так, как вы ожидали, и обновление отобразит модальную надпись на той же странице фона.
<Link to="/one" state={{login: true}}>/one with login state</Link>
<Link to="/two" state={{login: true}}>/two with login state</Link>
Вы можете также ссылку на страницу ток, добавления конкретных модальный.
const path = props.location.pathname;
<Link to={path} state={{login: true}}>current path + login state</Link>
<Link to={path} state={{profile: true}}>current path + profile state</Link>
Конечно, в зависимости от того, как вы хотите, чтобы ваше приложение, чтобы работать, а не все это применимо и полезно. Например, если модальный действительно глобальный (то есть он может отображаться независимо от маршрута), это может работать нормально, но для модалов, таких как показ профиля данного пользователя, я, вероятно, сделаю это отдельный маршрут, гнездящийся его родитель, например:
<Route path="https://stackoverflow.com/users/:id" component={UserPage}>
<Route path="https://stackoverflow.com/users/:id/profile" component={UserProfile} />
</Route>
UserProfile
, в этом случае, будет компонентом, который оказывает модальность.
Другим примером, где вы можете внести изменения, является хранение определенных модалов в истории; если вы этого не хотите, используйте replaceState
вместо setState
, если необходимо.
Путь вы описываете это звучит как Вход/модальный не действительно маршрут на всех, так почему вы пытаетесь так относиться к этому? Это действительно «состояние» пользовательского интерфейса, которое может отображаться на уровне приложения, например, всякий раз, когда это необходимо. – WiredPrairie
Это не просто состояние, если вы хотите сделать более динамичный модальный, например '/ user /: uid/folder /: fid', и связать его по нескольким местам. Вход - всего лишь пример. – kromit
Для модов не-входа в систему, откуда бы они получили свое состояние? детский маршрут или где-то еще? –