Я новичок в React и React Router.Я пытался создать одностраничное приложение, которое имеет макет с панелями навигации и содержимым, а также страницу входа, которая не загружается внутри этого макета.Я искал в Интернете и stackoverflow, но не смог понять это.Чтобы создать свое приложение, я использовал «yarn create activ-app appName» и использовал «yarn add», чтобы добавить реагирующий маршрутизатор.Как мне нужно создать свои маршруты таким образом, чтобы у меня была страница входа с собственным макетом и основной макет, где мой контент может отображаться.
Вот мой index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();
Вот мой App.js:
import React, { Component } from 'react';
import Main from "./Main";
import Login, {fakeAuth} from "./components/Login";
import {
Route,
NavLink,
HashRouter,
Redirect,
withRouter,
Switch,
BrowserRouter
} from "react-router-dom";
class App extends Component {
render() {
return (
<BrowserRouter>
<Switch>
<Route exact path="/" component={Main} />
<Route path="/login" component={Login} />
</Switch>
</BrowserRouter>
);
}
}
export default App;
Вот мой Login.js:
import React from 'react';
import {
Route,
NavLink,
HashRouter,
Redirect
} from "react-router-dom";
class Login extends React.Component {
constructor() {
super();
this.state = {
redirectToReferrer: false
}
this.login = this.login.bind(this);
}
login() {
fakeAuth.authenticate(() => {
this.setState({ redirectToReferrer: true })
})
}
render() {
const { from } = this.props.location.state || { from: {
pathname: '/' } }
const { redirectToReferrer } = this.state;
if (redirectToReferrer) {
return (
<Redirect to={from} />
)
}
return (
<div>
<p>You must log in to view the page at {from.pathname}</p>
<button onClick={this.login}>Log in</button>
</div>
)
}
}
/* A fake authentication function */
export const fakeAuth = {
isAuthenticated: false,
authenticate(cb) {
this.isAuthenticated = true;
setTimeout(cb, 100);
}
};
export default Login
Вот мой Main.js:
import React, { Component } from 'react';
import Navigation from './components/Navigation'
import LeftSidebar from './components/LeftSidebar';
import RightSidebar from './components/RightSidebar';
import Login, {fakeAuth} from "./components/Login";
import {
Route,
NavLink,
HashRouter,
Redirect,
withRouter,
Switch
} from "react-router-dom";
/* Home component */
const Home = () => (
<div>
<h2>Home</h2>
</div>
)
/* Category component */
const Category = () => (
<div>
<h2>Category</h2>
</div>
)
/* Products component */
const Products = () => (
<div>
<h2>Products</h2>
</div>
)
class Main extends Component {
render() {
return (
<HashRouter>
<div className="container container-fluid">
<Navigation/>
<div className="row">
<div className="col-md-3">
<LeftSidebar/>
</div>
<div className="col-md-6">
<Route exact path="/" component={Home} />
<Route path="/category" component={Category}/>
<PrivateRoute authed={fakeAuth.isAuthenticated} path='/products' component = {Products} />
</div>
<div className="col-md-3">
<RightSidebar/>
</div>
</div>
</div>
</HashRouter>
);
}
}
const PrivateRoute = ({ component: Component, ...rest }) => {
return (
<Route
{...rest}
render={props =>
fakeAuth.isAuthenticated === true ? (
<Component {...props} />
) : (
<Redirect
to={{ pathname: "/login", state: { from: props.location }
}}
/>
)}
/>
);
};
const AuthButton = withRouter(
({ history }) =>
fakeAuth.isAuthenticated ? (
<p>
Welcome!{" "}
<button
onClick={() => {
fakeAuth.signout(() => history.push("/"));
}}
>
Sign out
</button>
</p>
) : (
<p>You are not logged in.</p>
)
);
export default Main;
Мои ссылки на маршруты находятся в моем компоненте навигации:
....
<ul>
<li><Link to="/">Homes</Link></li>
<li><Link to="/category">Category</Link></li>
<li><Link to="/products">Products</Link></li>
</ul>
....
Когда я нажимаю ссылку Домой, Категория или Продукты, я хочу, чтобы компонент загружался в макете SPA в Main.js, и я хочу Войти.js для загрузки на своей странице.Прямо сейчас, Главная, Категория, Продукты и Логин загружаются в основной макет.Что мне нужно изменить в этих маршрутах или другой части моего кода, чтобы это работало?
Редактировать:
Добавлен мой код авторизации в классе Main.js.Добавлен класс Login.js.
В дополнение к некоторым учебникам по этому вопросу, я следую совету из этого ответа: Страница входа, отделенная от одностраничного приложения (SPA) в ReactJS Однако я не совсем понимаю.Я не уверен, что именно мне нужно добавить, чтобы сделать эту работу.
Вот изображения, иллюстрирующие то, что я пытаюсь сделать:
Main.js: основной макет SPA
Login.js: Страница входа
Текущая проблема - логин загружается в основной макет, а не на свою собственную страницу: НЕ хотите этого